You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中比对含同名列的异结构DataFrame差异实现方法

pandas 非对齐DataFrame按关联键差异比对实现

pandas内置的.compare()方法强制要求两个输入DataFrame的列名、索引完全对齐,你的场景下两个表列数、行数都不一致,且需要按Sport字段做关联匹配,没法直接调用该方法,可按以下逻辑实现:

核心判定逻辑拆分

  • 处理abc存在、xyz缺失的Sport值:直接标注不存在
  • 处理xyz存在、abc缺失的Sport值:输出对应SportLeague值,标注为待删除
  • 处理两边共有的Sport值:逐行匹配Year、ID字段,任意字段不一致则记录差异,输出对应SportLeague作为标识

可直接运行的实现代码

import pandas as pd
import numpy as np

# 测试用例数据
abc = {'Sport' : ['Football', 'Basketball', 'Baseball', 'Hockey'], 'Year' : ['2021','2021','2022','2022'], 'ID' : ['1','2','3','4']}
abc = pd.DataFrame(abc)
xyz = {'Sport' : ['Football', 'Football', 'Basketball', 'Baseball', 'Hockey', 'Soccer'], 'SportLeague' : ['Football:NFL', 'Football:XFL', 'Basketball:NBA', 'Baseball:MLB', 'Hockey:NHL', 'Soccer:MLS'], 'Year' : ['2022','2019', '2022','2022','2022', '2022'], 'ID' : ['2','0', '3','2','4', '1']}
xyz = pd.DataFrame(xyz).sort_values(by=['ID'], ascending=True)

diff_records = []
# 提取两边Sport字段的集合
abc_sports = set(abc['Sport'])
xyz_sports = set(xyz['Sport'])

# 1. 判定abc存在但xyz缺失的Sport
for sport in abc_sports - xyz_sports:
    diff_records.append({
        "匹配标识": sport,
        "差异内容": "Not Found in `xyz data frame`"
    })

# 2. 判定xyz存在但abc缺失的Sport
for _, row in xyz[~xyz['Sport'].isin(abc_sports)].iterrows():
    league_tag = row['SportLeague']
    diff_records.append({
        "匹配标识": league_tag,
        "差异内容": f"Remove `{league_tag}`"
    })

# 3. 判定两边共有的Sport下Year、ID字段的差异
for _, xyz_row in xyz[xyz['Sport'].isin(abc_sports)].iterrows():
    league_tag = xyz_row['SportLeague']
    xyz_year, xyz_id = xyz_row['Year'], xyz_row['ID']
    # 取abc中同Sport的对应记录
    abc_match = abc[abc['Sport'] == xyz_row['Sport']].iloc[0]
    abc_year, abc_id = abc_match['Year'], abc_match['ID']
    if (xyz_year != abc_year) or (xyz_id != abc_id):
        diff_records.append({
            "匹配标识": league_tag,
            "差异内容": f"Change from {xyz_year} and {xyz_id} to {abc_year} and {abc_id}"
        })

# 转换为DataFrame输出,仅保留存在差异的记录
diff_result = pd.DataFrame(diff_records)
print(diff_result)

测试用例运行输出

匹配标识                                 差异内容
0   Soccer:MLS                          Remove `Soccer:MLS`
1  Football:XFL  Change from 2019 and 0 to 2021 and 1
2  Football:NFL  Change from 2022 and 2 to 2021 and 1
3  Baseball:MLB  Change from 2022 and 2 to 2022 and 3

适配说明

  • 兼容同一个Sport在xyz中对应多条记录(如示例中Football对应NFL、XFL两个联赛条目)的场景,会逐行校验不遗漏
  • 输出的匹配标识统一使用xyz表的SportLeague字段值,符合输出要求,不会直接返回Sport原值
  • 无需提前对齐两个表的索引、列数、行数,不存在内置compare方法的列不匹配报错问题

内容的提问来源于stack exchange,提问作者HelpMeCode

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 12:24:24