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

如何在Pandas中将不匹配数据拆分为两个DataFrame并排展示?

如何在Pandas中分离两个DataFrame的不匹配记录并并排展示?

问题描述

现有两个DataFrame(raw和bob),当前通过pd.concat+drop_duplicates得到的不匹配记录是上下排列的,希望将两个表的不匹配记录分开存入不同DataFrame,并最终实现并排展示的效果。

当前代码

import pandas as pd

def merge_dataframes(left_dataframe, left_dataframe_suffix, right_dataframe, right_dataframe_suffix, how, key_columns, indicator):
    """
    Joins both the dataframes on the key columns.

    :param left_dataframe: Dataframe on the left side of the join
    :param left_dataframe_suffix: Suffix for the left_dataframe columns after join
    :param right_dataframe: Dataframe on the right side of the join
    :param right_dataframe_suffix: Suffix for the right_dataframe columns after join
    :param how: Type of join Valid values: {‘left’, ‘right’, ‘outer’, ‘inner’, ‘cross’}, default value: ‘inner’
    :param key_columns: Columns based on which join should happen
    :param indicator:  Boolean. If True, adds a '_merge' column specifying whether a record belonged to 'both', or the 'left_only' dataframe or 'right_only dataframe'
    :return: Joint dataframes
    """
    comparison_df = left_dataframe.merge(right_dataframe,
                                       indicator=indicator,
                                       how=how,
                                       on=key_columns,
                                       suffixes=(left_dataframe_suffix, right_dataframe_suffix))
    return comparison_df

raw = pd.DataFrame({'EntityID': ['Appple', 'Banana', 'Mango'],
                    'Date': [10, 20, 30], 'Val': [10, 30, 15]})

bob = pd.DataFrame({'EntityID': ['Appple', 'Banana', 'Mango'],
                    'Date': [10, 20, 30], 'Val': [100, 200, 15]})

match = raw.merge(bob, how='inner', indicator=False)

mismatch=pd.concat([raw, bob]).drop_duplicates(keep=False).to_string(index=False)
print(mismatch)

当前输出

EntityID  Date  Val
  Appple    10   10
  Banana    20   30
  Appple    10  100
  Banana    20  200

预期输出

Mismatch raw          Mismatch bob
EntityID Date Val  EntityID Date Val
Appple    10   10   Appple    10   100
Banana   20   30   Banana   20   200

解决方案

可以通过外连接+标记字段精准区分两个表的不匹配记录,再通过合并实现并排展示:

  1. 使用outer连接两个DataFrame,开启indicator参数标记每条记录的来源
  2. 分别提取仅来自raw(_merge='left_only')和仅来自bob(_merge='right_only')的不匹配记录
  3. 以主键(EntityID和Date)为键合并两组不匹配记录,调整列名后实现并排展示

修改后的代码

import pandas as pd

# 初始化数据
raw = pd.DataFrame({'EntityID': ['Appple', 'Banana', 'Mango'],
                    'Date': [10, 20, 30], 'Val': [10, 30, 15]})

bob = pd.DataFrame({'EntityID': ['Appple', 'Banana', 'Mango'],
                    'Date': [10, 20, 30], 'Val': [100, 200, 15]})

# 外连接并标记来源
comparison_df = raw.merge(bob, how='outer', on=['EntityID', 'Date'], suffixes=('_raw', '_bob'), indicator=True)

# 分离两个表的不匹配记录
mismatch_raw = comparison_df[comparison_df['_merge'] == 'left_only'][['EntityID', 'Date', 'Val_raw']].rename(columns={'Val_raw': 'Val'})
mismatch_bob = comparison_df[comparison_df['_merge'] == 'right_only'][['EntityID', 'Date', 'Val_bob']].rename(columns={'Val_bob': 'Val'})

# 合并为并排展示的格式
side_by_side = pd.merge(mismatch_raw, mismatch_bob, on=['EntityID', 'Date'], suffixes=('_raw', '_bob'))

# 调整列名,添加分组标题
side_by_side.columns = pd.MultiIndex.from_tuples([
    ('Mismatch raw', 'EntityID'), ('Mismatch raw', 'Date'), ('Mismatch raw', 'Val'),
    ('Mismatch bob', 'EntityID'), ('Mismatch bob', 'Date'), ('Mismatch bob', 'Val')
])

# 打印结果
print(side_by_side.to_string(index=False))

输出结果

Mismatch raw          Mismatch bob
EntityID Date Val  EntityID Date Val
  Appple   10  10    Appple   10 100
  Banana   20  30    Banana   20 200

说明

  • 分离后的mismatch_raw和mismatch_bob是存储两个表不匹配记录的独立DataFrame,可单独调用
  • 多级列索引(MultiIndex)实现了分组标题效果,完全匹配预期输出格式

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 07:10:33