按指定列筛选DataFrame差异行时列名变更引发KeyError问题
解决按指定列筛选df1中不存在于df2的行时的KeyError问题
问题根源在于你执行merge时传入了完整的df2(包含非匹配列col2),pandas会对两个DataFrame中同名但未用于连接的列自动添加_x(来自df1)和_y(来自df2)后缀,导致合并后的DataFrame里没有原col2列,所以用df1.columns筛选时触发KeyError。
修正方案1:仅传入df2中用于匹配的列
只保留df2里需要用来匹配的col1和col3列,这样merge后不会生成多余的列,原df1的列名也不会被修改:
import pandas as pd df1 = pd.DataFrame(data = {'col1' : [1, 2, 3, 4, 5, 3], 'col2' : [10, 11, 12, 13, 14, 10], 'col3' : [1,5,7,9,6,7]}) df2 = pd.DataFrame(data = {'col1' : [1, 2, 3], 'col2' : [10, 11, 12], 'col3' : [1,5,8]}) # 只取df2中用于匹配的列,避免多余列导致后缀 df_merge = df1.merge(df2[['col1','col3']].drop_duplicates(), on=['col1','col3'], how='left', indicator=True) df_merge = df_merge.query("_merge == 'left_only'")[df1.columns] print(df_merge)
修正方案2:指定后缀并手动映射原列名
如果需要保留df2的非匹配列,可以通过suffixes参数自定义后缀,之后再筛选原df1的列:
import pandas as pd df1 = pd.DataFrame(data = {'col1' : [1, 2, 3, 4, 5, 3], 'col2' : [10, 11, 12, 13, 14, 10], 'col3' : [1,5,7,9,6,7]}) df2 = pd.DataFrame(data = {'col1' : [1, 2, 3], 'col2' : [10, 11, 12], 'col3' : [1,5,8]}) # 指定后缀,避免默认的_x/_y混淆 df_merge = df1.merge(df2.drop_duplicates(), on=['col1','col3'], how='left', indicator=True, suffixes=('', '_df2')) # 筛选原df1的列(此时col2未被重命名) df_merge = df_merge.query("_merge == 'left_only'")[df1.columns] print(df_merge)
替代方案:用isin结合元组匹配
不需要merge,直接通过将指定列转为元组的方式判断是否存在于df2中:
import pandas as pd df1 = pd.DataFrame(data = {'col1' : [1, 2, 3, 4, 5, 3], 'col2' : [10, 11, 12, 13, 14, 10], 'col3' : [1,5,7,9,6,7]}) df2 = pd.DataFrame(data = {'col1' : [1, 2, 3], 'col2' : [10, 11, 12], 'col3' : [1,5,8]}) # 将df2的匹配列转为元组集合 df2_match_set = set(df2[['col1','col3']].itertuples(index=False, name=None)) # 筛选df1中不在集合里的行 result = df1[~df1[['col1','col3']].itertuples(index=False, name=None).isin(df2_match_set)] print(result)
内容的提问来源于stack exchange,提问作者Digital Farmer
相关产品推荐
相关产品推荐

