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

对比两个DataFrame,定位数据不匹配的行、列及对应值

DataFrame数据对比与不匹配信息提取

需求说明

我有两个DataFrame需要对比,需返回数据不匹配发生的行号、列名,以及实际值与预期值的对应信息。两个DataFrame均包含ID、Name、Location、Program列,要求输出格式如下:

Mismatched Rows: (Row 2, columns=[channelName,sublobName]),(Row 3, columns=[sublobName])

原始代码(存在问题)

df_actual = pd.DataFrame({'Partner': ['P1', 'P2', 'P3'],
                       'lobName': ['L1', 'L2', 'L3'],
                       'sublobName': ['S1', 'S2', 'S3'],
                       'channelName': ['C1', 'C5', 'C3'],
                       'value1': [1, 2, 3]})
df_rpt_all1 = pd.DataFrame({'Partner': ['P1', 'P2', 'P3'],
                             'lobName': ['L1', 'L2', 'L3'],
                             'sublobName': ['S1', 'S2', 'S3'],
                             'channelName': ['C1', 'C2', 'C3'],
                             'value1': [1, 2, 6]})

merged_df = df_rpt_all1.merge(df_actual, how='left', on=['ID','Name','Location','Program'], indicator=True)

mismatched_info = []
for index, row in merged_df.iterrows():
    if row['_merge'] == 'left_only':
        non_matching_cols = []
        non_matching_vals = []
        for col in merged_df.columns:
            if col.endswith('_x') and row[col] != row[col.replace('_x', '_y')]:
                non_matching_cols.append(col)
                non_matching_vals.append(row[col])
        mismatched_info.append(f"(Row {index + 1}, columns={non_matching_cols}, values={dict(zip(non_matching_cols, non_matching_vals))})")

if mismatched_info:
    result = '\n'.join(mismatched_info)
    print(f"Mismatched Rows:\n{result}")
else:
    print("No mismatches found.")

问题分析与修正方案

原始代码的问题

  1. 合并键错误:代码中用['ID','Name','Location','Program']作为合并键,但实际定义的DataFrame里只有Partner、lobName等列,不存在这些键,导致合并后无法正确匹配行。
  2. 不匹配判断逻辑错误:left_only只代表左表有但右表没有的行,但我们需要的是同一主键行中列值不匹配的情况,而非行存在性差异。
  3. 列名处理错误:对比时保留了_x、_y后缀,应该还原为原始列名,同时需要同时记录预期值和实际值。

修正后的代码

import pandas as pd

# 定义两个DataFrame(这里假设用Partner作为唯一标识主键,实际可替换为ID等列)
df_actual = pd.DataFrame({'Partner': ['P1', 'P2', 'P3'],
                       'lobName': ['L1', 'L2', 'L3'],
                       'sublobName': ['S1', 'S2', 'S3'],
                       'channelName': ['C1', 'C5', 'C3'],
                       'value1': [1, 2, 3]})
df_expected = pd.DataFrame({'Partner': ['P1', 'P2', 'P3'],
                             'lobName': ['L1', 'L2', 'L3'],
                             'sublobName': ['S1', 'S2', 'S3'],
                             'channelName': ['C1', 'C2', 'C3'],
                             'value1': [1, 2, 6]})

# 用主键合并两个表,区分预期值和实际值的后缀
merged_df = df_expected.merge(df_actual, on='Partner', suffixes=('_expected', '_actual'), indicator=True)

mismatched_info = []
# 遍历每一行
for idx, row in merged_df.iterrows():
    row_num = idx + 1
    non_matching_cols = []
    # 遍历所有需要对比的列(排除主键)
    for col in df_expected.columns:
        if col == 'Partner':
            continue
        expected_val = row[f"{col}_expected"]
        actual_val = row[f"{col}_actual"]
        # 处理空值情况,避免NaN != NaN的逻辑错误
        if pd.notna(expected_val) and pd.notna(actual_val):
            if expected_val != actual_val:
                non_matching_cols.append(col)
        elif pd.isna(expected_val) != pd.isna(actual_val):
            # 一个为空一个不为空,判定为不匹配
            non_matching_cols.append(col)
    # 记录不匹配信息
    if non_matching_cols:
        col_str = f"[{','.join(non_matching_cols)}]"
        mismatched_info.append(f"(Row {row_num}, columns={col_str})")

# 输出结果
if mismatched_info:
    result = ','.join(mismatched_info)
    print(f"Mismatched Rows: {result}")
else:
    print("No mismatches found.")

输出结果

运行修正后的代码,会得到符合要求的输出:

Mismatched Rows: (Row 2, columns=[channelName]),(Row 3, columns=[value1])

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 09:25:57