使用Pandas对比两个DataFrame,分离显示不匹配行及缺失行
Pandas对比同结构DataFrame:找出差异行与缺失行
前提说明
假设你的两个DataFrame有唯一标识列(如id),这是高效对比的核心;如果没有唯一键,后面会补充无标识的处理方式。
示例数据
先构造模拟数据复现场景:
import pandas as pd # df1:原始数据 df1 = pd.DataFrame({ 'id': [1, 2, 3, 4], 'name': ['Alice', 'Bob', 'Charlie', 'David'], 'age': [25, 30, 35, 40], 'city': ['New York', 'London', 'Paris', 'Tokyo'] }) # df2:修改+新增数据 df2 = pd.DataFrame({ 'id': [2, 3, 4, 5], 'name': ['Bob', 'Charlie', 'Dave', 'Eve'], 'age': [31, 35, 40, 28], 'city': ['London', 'Berlin', 'Tokyo', 'Sydney'] })
1. 提取df2视角对比df1的缺失行
即df2存在但df1没有的行:
# 利用唯一id快速筛选 df2_missing = df2[~df2['id'].isin(df1['id'])].copy() print("=== df2视角下df1的缺失行 ===") print(df2_missing)
输出结果:
id name age city 3 5 Eve 28 Sydney
2. 找出两表不匹配行并展示差异值
针对双方都存在的行,对比列值差异并格式化展示:
# 合并两表,仅保留双方都有的id,添加后缀区分来源 merged = pd.merge(df1, df2, on='id', how='inner', suffixes=('_df1', '_df2')) # 筛选出至少有一列值不同的行 diff_mask = (merged.filter(like='_df1') != merged.filter(like='_df2')).any(axis=1) diff_rows = merged[diff_mask] # 整理差异为可读格式:差异列显示「原值→新值」,相同列保留原值 diff_details = [] for _, row in diff_rows.iterrows(): diff_dict = {'id': row['id']} for col in df1.columns.drop('id'): val1, val2 = row[f'{col}_df1'], row[f'{col}_df2'] diff_dict[col] = f"{val1} -> {val2}" if val1 != val2 else val1 diff_details.append(diff_dict) diff_result = pd.DataFrame(diff_details) print("\n=== 两表不匹配行及差异值 ===") print(diff_result)
输出结果:
id name age city 0 2 Bob 30 -> 31 London 1 3 Charlie 35 Paris -> Berlin 2 4 David -> Dave 40 Tokyo
无唯一标识列的处理方式
如果没有专属的唯一键,可通过以下方式处理:
2.1 对比差异行
# 重置索引确保行对齐 df1_reset = df1.reset_index(drop=True) df2_reset = df2.reset_index(drop=True) # 直接用Pandas内置compare方法,仅展示不同值 diff_result = df1_reset.compare(df2_reset, keep_equal=False) print("\n=== 无唯一键时的差异对比 ===") print(diff_result)
2.2 提取df2视角的缺失行
# 全量合并并标记来源 full_merge = pd.merge(df1, df2, how='outer', indicator=True) # 筛选仅在df2中存在的行 df2_missing = full_merge[full_merge['_merge'] == 'right_only'].drop(columns='_merge') print("\n=== 无唯一键时df2视角的缺失行 ===") print(df2_missing)
内容的提问来源于stack exchange,提问作者sugnez
相关产品推荐
相关产品推荐

