基于另一DataFrame公共列匹配替换Pandas DataFrame指定列值
问题解决:Pandas多列匹配替换指定列值
原代码问题分析
- 变量名不一致:你定义的存储键列的变量名为
columns,后续判断时误用了cols,会直接触发NameError。 - 维度不匹配:df1和df2行数不同,
df1[cols] == df2[cols].values会因两个数组行数不一致无法广播,直接运行报错。 - 链式赋值风险:写法
df1.loc[...]['Col4'] = 100属于链式赋值,就算筛选条件正确,也可能因返回的是DataFrame副本导致赋值不生效,正确的赋值格式为df1.loc[筛选条件, 目标列名] = 100。
正确实现方法
方法1:小数据量适用,元组匹配法
把两个DataFrame的匹配键列按行转为元组,通过集合成员判断快速筛选匹配行,写法简单直观:
import pandas as pd # 测试数据构造 df1 = pd.DataFrame([['A','b','x',1], ['A','b','y',2], ['A','c','z',3], ['B','b','x',4]], columns=['Col1', 'Col2', 'Col3', 'Col4']) df2 = pd.DataFrame([['A','b','y',0], ['B','b','x',0]], columns=['Col1','Col2','Col3','Col4']) # 指定匹配用的键列 key_cols = ['Col1', 'Col2', 'Col3'] # 将df2的键列转为元组集合,用于快速匹配 match_keys = set(df2[key_cols].apply(tuple, axis=1)) # 筛选匹配行,直接替换Col4值 df1.loc[df1[key_cols].apply(tuple, axis=1).isin(match_keys), 'Col4'] = 100
方法2:大数据量适用,merge标记法
通过左连接生成匹配标记列,底层用哈希连接实现,数据量上万时性能远高于逐行apply的方式:
key_cols = ['Col1', 'Col2', 'Col3'] # 左连接新增匹配标记列 df1 = df1.merge(df2[key_cols], on=key_cols, how='left', indicator='_is_match') # 匹配到的行替换目标值 df1.loc[df1['_is_match'] == 'both', 'Col4'] = 100 # 删除临时标记列 df1 = df1.drop('_is_match', axis=1)
两种方法执行后都可以得到你预期的df1结果。
内容的提问来源于stack exchange,提问作者Fhtsm
相关产品推荐
相关产品推荐

