如何合并两个Pandas DataFrame并仅保留存在差异的行与列
高效对比Pandas DataFrame并仅保留差异行和列
针对你的需求,下面提供两种场景的解决方案,覆盖行内列值差异和行仅存在于单个DataFrame的情况,同时自动筛选出有差异的列,适配300+列的场景:
场景1:两个DataFrame的维度行完全对齐(无缺失行)
如果df1和df2的pet_name+exam_day组合完全一致,仅存在列值差异,可以按以下步骤处理:
import pandas as pd # 1. 将维度列设为索引,方便逐行逐列对比 df1_indexed = df1.set_index(['pet_name', 'exam_day']) df2_indexed = df2.set_index(['pet_name', 'exam_day']) # 2. 筛选出至少有一个列值不同的行 diff_rows_mask = df1_indexed.ne(df2_indexed).any(axis=1) # 3. 筛选出至少有一个行值不同的列 diff_cols_mask = df1_indexed.ne(df2_indexed).any(axis=0) # 4. 提取差异行+差异列,同时保留新旧值对比(添加后缀区分) diff_result = df1_indexed[diff_rows_mask].join( df2_indexed[diff_rows_mask], lsuffix='_old', rsuffix='_new' )[diff_cols_mask.index] # 重置索引,恢复维度列为普通列 diff_result = diff_result.reset_index()
这段代码会自动只保留pet_name、exam_day以及存在差异的列,每个差异列会显示_old(df1的值)和_new(df2的值),清晰展示差异。
场景2:存在仅在单个DataFrame中出现的行
如果需要同时保留只在df1或df2中存在的行,结合你原来的merge逻辑,补充如下:
# 先执行场景1的步骤得到diff_result # 然后找出仅在单个DataFrame存在的行 only_in_df1 = df1[~df1.set_index(['pet_name', 'exam_day']).index.isin(df2.set_index(['pet_name', 'exam_day']).index)] only_in_df2 = df2[~df2.set_index(['pet_name', 'exam_day']).index.isin(df1.set_index(['pet_name', 'exam_day']).index)] # 为单独存在的行添加后缀,方便区分来源 only_in_df1 = only_in_df1.add_suffix('_old') only_in_df2 = only_in_df2.add_suffix('_new') # 合并所有差异结果并排序 final_result = pd.concat([diff_result, only_in_df1, only_in_df2]).sort_values(['pet_name', 'exam_day'])
关键逻辑说明
ne()方法:逐元素比较两个DataFrame是否不等,返回布尔值矩阵any(axis=1):检查每行是否有至少一个不等值,筛选出差异行any(axis=0):检查每列是否有至少一个不等值,筛选出差异列- 用索引对齐保证行匹配,避免merge带来的列冗余问题
内容的提问来源于stack exchange,提问作者ohh
相关产品推荐
相关产品推荐

