无需遍历:基于EID对比两个Pandas DataFrame,识别匹配、差异与缺失值
Pandas DataFrame 批量列对比:基于EID识别匹配、差异与缺失值
现有两个Pandas DataFrame(DF1和DF2),需基于相同的EID值,对比DF2与DF1中的同名列(示例为Col1、Col2、Col3),识别每行的匹配、差异、缺失值情况。由于实际数据包含70-100列,要求避免逐行遍历以提升效率。
示例数据
DF1
EID Col1 Col2 Col3 Col4 0 A a1 b1 c1 d1 1 B a2 b2 c2 d2 2 C None b3 c3 d3 3 D a4 b4 c4 d4 4 G a5 b5 c5 d5
DF2
EID Col1 Col2 Col3 0 A a1 b1 c1 1 B a2 b2 c9 2 C a3 b3 c3 3 D a4 b4 None
预期输出
EID Col1 Col2 Col3 New_Col 0 A a1 b1 c1 Match 1 B a2 b2 c2 Different 2 C None b3 c3 Missing in DF1 3 D a4 b4 c4 Missing in DF2
解决方案
核心思路
利用Pandas的矢量化操作替代逐行遍历,通过合并、批量标记、结果整理三步完成,适配多列场景。
完整实现代码
import pandas as pd # 构造示例数据(替换为你的实际DataFrame即可) DF1 = pd.DataFrame({ 'EID': ['A', 'B', 'C', 'D', 'G'], 'Col1': ['a1', 'a2', None, 'a4', 'a5'], 'Col2': ['b1', 'b2', 'b3', 'b4', 'b5'], 'Col3': ['c1', 'c2', 'c3', 'c4', 'c5'], 'Col4': ['d1', 'd2', 'd3', 'd4', 'd5'] }) DF2 = pd.DataFrame({ 'EID': ['A', 'B', 'C', 'D'], 'Col1': ['a1', 'a2', 'a3', 'a4'], 'Col2': ['b1', 'b2', 'b3', 'b4'], 'Col3': ['c1', 'c9', 'c3', None] }) # 自动获取两个DF的同名列(排除EID) common_cols = [col for col in DF1.columns if col in DF2.columns and col != 'EID'] # 1. 内连接两个DF,为区分同名列给DF1的列加后缀 merged_df = pd.merge(DF1[['EID'] + common_cols], DF2[['EID'] + common_cols], on='EID', suffixes=('_df1', ''), how='inner') # 2. 批量标记各类情况 # 标记DF1/DF2中的缺失值 df1_missing = merged_df[[f"{col}_df1" for col in common_cols]].isna() df2_missing = merged_df[common_cols].isna() # 标记值不匹配的情况(排除缺失值场景) values_diff = merged_df[[f"{col}_df1" for col in common_cols]].eq(merged_df[common_cols]) == False # 按优先级赋值New_Col merged_df['New_Col'] = 'Match' merged_df.loc[df1_missing.any(axis=1), 'New_Col'] = 'Missing in DF1' merged_df.loc[df2_missing.any(axis=1), 'New_Col'] = 'Missing in DF2' # 最后标记纯值差异的行 diff_mask = values_diff.any(axis=1) & ~df1_missing.any(axis=1) & ~df2_missing.any(axis=1) merged_df.loc[diff_mask, 'New_Col'] = 'Different' # 3. 整理输出格式,将列值替换为DF1的原始值 for col in common_cols: merged_df[col] = merged_df[f"{col}_df1"] # 生成最终输出 final_output = merged_df[['EID'] + common_cols + ['New_Col']] print(final_output)
代码说明
- 自动匹配同名列:通过列表推导式自动获取两个DF的共有列,无需手动指定,适配70-100列的场景。
- 矢量化标记:利用
isna()、eq()等矢量化方法批量生成标记矩阵,比逐行遍历效率提升数倍。 - 优先级赋值:先处理缺失值场景,再处理值差异场景,避免逻辑冲突。
内容的提问来源于stack exchange,提问作者Shashank Shekher
相关产品推荐
相关产品推荐

