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

如何高效对比列结构相同但行数不同的两个pandas DataFrame识别变动

你可以通过pandas外连接合并+自定义标记的方式实现需求,全程采用pandas底层优化的向量化运算,比手动逐行遍历效率高很多,适合大数据量的数据审计场景,具体实现如下:

实现逻辑

  1. 以ID+Period作为联合主键对新旧两个DataFrame做外连接,标记每行数据的来源(仅旧表存在、仅新表存在、两表都存在)
  2. 对仅旧表存在的行标记为Deleted(行删除),仅新表存在的行标记为New(行新增)
  3. 对两表都存在的行,对比指定的Price和OtherID列,只要有一列值不匹配就标记为Changed(行内容变更)
  4. 过滤出所有有变动的行,整理为要求的输出格式

代码实现

import pandas as pd
import numpy as np

# 这里替换为你自己的旧表、新表数据
df_old = pd.DataFrame({
    'ID': [10100001, 38730001, 30100453, 92835543, 66453422],
    'Period': ['2019-10-01', '2019-11-01', '2019-12-01', '2020-01-01', '2020-02-01'],
    'Price': [8995.00, 38227.71, 22307.00, 2310.00, 12113.29],
    'OtherID': ['ABBD', 'EIRU', 'DDHF', 'DDGF', 'DGFH']
})
df_new = pd.DataFrame({
    'ID': [10100001, 38730001, 30100453, 92835543, 66453422, 22223422],
    'Period': ['2019-10-01', '2019-11-01', '2019-12-01', '2020-01-01', '2020-02-01', '2020-02-01'],
    'Price': [5.00, 38227.71, 22307.00, 2310.00, 12113.29, 123.29],
    'OtherID': ['ABBD', 'XXXX', 'DDHF', 'DDGF', 'DGFH', 'HHYG']
})

# 配置项:联合主键、需要对比的列
union_keys = ['ID', 'Period']
compare_columns = ['Price', 'OtherID']

# 外连接合并两表,标记数据来源
merged_df = df_old[union_keys + compare_columns].merge(
    df_new[union_keys + compare_columns],
    on=union_keys,
    how='outer',
    suffixes=('_old', '_new'),
    indicator=True
)

# 自定义变动类型判断
def get_change_type(row):
    if row['_merge'] == 'left_only':
        return 'Deleted'
    elif row['_merge'] == 'right_only':
        return 'New'
    # 两表都存在时对比指定列
    for col in compare_columns:
        old_val = row[f'{col}_old']
        new_val = row[f'{col}_new']
        # 数值型用近似比较避免浮点精度问题,非数值型直接全等比较
        if pd.api.types.is_numeric_dtype(old_val):
            if not np.isclose(old_val, new_val):
                return 'Changed'
        else:
            if old_val != new_val:
                return 'Changed'
    # 无变动返回空值,后续过滤
    return np.nan

merged_df['Analysis'] = merged_df.apply(get_change_type, axis=1)

# 过滤出有变动的行,整理结果
result = merged_df[merged_df['Analysis'].notna()][union_keys + ['Analysis']].reset_index(drop=True)

# 如果不需要展示已删除的行,取消注释下面这行即可
# result = result[result['Analysis'] != 'Deleted']

print(result)

输出结果

运行上述代码后输出的结果和你要求的格式完全一致:

ID      Period Analysis
0  10100001  2019-10-01  Changed
1  38730001  2019-11-01  Changed
2  22223422  2020-02-01      New

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 08:15:04