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

如何对比两个DataFrame同ID的差异值并精准输出结果?

解决按ID对比两个DataFrame列值差异的问题

问题分析

你当前的代码使用pd.merge(df1, df2, on=['id'], how='inner')会对每个ID下的行做笛卡尔积组合,比如ID=1时,df1的2行和df2的2行会生成4行数据。这时候用check_column1 != check_column2判断,会把很多只是顺序不同的行误判为差异,导致输出结果错误。

你的核心需求是:按ID分组,找出两个表中该ID下独有的列值,并输出对应的差异行。

解决方案代码

import pandas as pd

# 构造示例数据
df1 = pd.DataFrame({
    'id': [1, 1, 2, 2, 2],
    'check_column1': ['abc', 'bcd', 'xyz', 'mno', 'mmm']
})

df2 = pd.DataFrame({
    'id': [1, 1, 2, 2, 2],
    'check_column2': ['bcd', 'abc', 'xyz', 'mno', 'kkk']
})

# 1. 按ID分组,获取每个ID对应的列值集合(自动去重、忽略顺序)
df1_id_sets = df1.groupby('id')['check_column1'].apply(set).reset_index(name='col1_set')
df2_id_sets = df2.groupby('id')['check_column2'].apply(set).reset_index(name='col2_set')

# 2. 合并分组结果,计算每个ID的对称差异(两边独有的值)
id_diff = pd.merge(df1_id_sets, df2_id_sets, on='id')
id_diff['unique_values'] = id_diff.apply(lambda x: x['col1_set'].symmetric_difference(x['col2_set']), axis=1)

# 3. 筛选出存在差异的ID,并拆分两边独有的值
id_diff = id_diff[id_diff['unique_values'].apply(len) > 0]
id_diff['df1_unique'] = id_diff.apply(lambda x: x['col1_set'] - x['col2_set'], axis=1)
id_diff['df2_unique'] = id_diff.apply(lambda x: x['col2_set'] - x['col1_set'], axis=1)

# 4. 展开差异值,整理成最终输出格式
final_result = pd.merge(
    id_diff.explode('df1_unique')[['id', 'df1_unique']],
    id_diff.explode('df2_unique')[['id', 'df2_unique']],
    on='id',
    how='outer'
).rename(columns={'df1_unique': 'check_column1', 'df2_unique': 'check_column2'})

print(final_result)

输出结果

id check_column1 check_column2
0   2           mmm           kkk

关键步骤说明

  1. 分组取集合:通过groupby+apply(set),把每个ID下的列值转换成集合,自动忽略值的顺序和重复,只关注值的存在性。
  2. 计算对称差异:集合的symmetric_difference方法会返回两个集合中独有的值,正好对应需要的差异项。
  3. 展开差异值:把集合中的差异值展开成单独的行,保证输出格式符合预期。

如果数据中存在同一ID下多个差异值的情况,这段代码也能正确处理(比如ID=3的df1有a、b,df2有c、d,会输出两行对应差异)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 14:05:24