对比两个pandas.DataFrame 仅提取第一个DataFrame中存在差异的行
实现方案
有两种简单且和你原有对比逻辑一致的实现方法,如下:
方法1:用merge的indicator参数(最稳妥,不受索引影响)
该方案通过全字段匹配筛选仅在df1中存在的行,运行效率更高:
# 所有列作为匹配键,仅比对df1的行 df1_diff = df1.merge(df2, how='left', on=list(df1.columns), indicator=True) \ .query('_merge == "left_only"') \ .drop(columns=['_merge'])
参数说明:
on=list(df1.columns)指定所有列作为匹配依据,和你原有的drop_duplicates逻辑完全一致,只有所有列值完全相同才会判定为相同行indicator=True自动新增_merge列标记行的来源,left_only代表仅在左表(df1)存在- 最后删除新增的标记列即可得到目标结果
方法2:基于原有concat逻辑改造
如果你不想调整原有写法,只需要加来源标记筛选即可:
# 临时加来源标记区分两个表的行 df1['_src'] = 'left' df2['_src'] = 'right' # 原有对比逻辑,排除掉所有重复行 all_diff = pd.concat([df1, df2]).drop_duplicates(subset=list(df1.columns.drop('_src')), keep=False) # 筛选仅属于df1的差异行 df1_diff = all_diff[all_diff['_src'] == 'left'].drop(columns=['_src']) # 清理两个原表的临时标记列,避免影响后续使用 df1.drop(columns=['_src'], inplace=True) df2.drop(columns=['_src'], inplace=True)
注意事项
- 如果只需要对比部分列判定是否相同,把
on参数或者subset参数的列列表替换为你要对比的列即可 - pandas默认NaN和NaN判定为不相等,如果需要把NaN视为相同值,可以在对比前用
df.fillna('自定义占位符')统一处理空值
内容的提问来源于stack exchange,提问作者bugZ
相关产品推荐
相关产品推荐

