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

如何比较两个Pandas DataFrame并提取变更记录用于SQL更新

对比Pandas DataFrame并生成SQL更新用数据集

需求说明

需要编写Python脚本对比两个DataFrame:df1是从现有SQL表读取的旧数据,df2是API拉取的新数据。目标是筛选出任意字段值有变更或新增的记录,生成结构和原表一致的新DataFrame,用于更新SQL表。

之前用外连接的方法没得到正确结果,返回了完整的合并DataFrame,需要修正。

示例说明

  • df1(旧数据):包含主键及业务字段,比如ID、Name、Age、City,部分记录如ID=1(Alice,25,NY)、ID=2(Bob,30,LA)
  • df2(新数据):同结构,部分字段变更(如ID=1的Age变为26)、新增记录(ID=3)、字段变更(ID=4的City从CHI改为DAL)
  • 期望输出:仅包含ID=1(Age变更)、ID=3(新增)、ID=4(City变更)的记录,用df2的新值,结构和原表一致

原代码问题

原代码仅通过df_merged.isna().any(axis=1)筛选存在空值的行,只能识别新增/删除的记录,无法检测到非空但值不同的字段变更,所以返回了全部数据。

修正后的解决方案

完整代码

import pandas as pd

def compare_dataframes(df1, df2, pk_col):
    # 按主键外连接,保留两边所有记录
    df_merged = pd.merge(df1, df2, on=pk_col, how='outer', suffixes=('_old', '_new'))
    
    # 获取所有非主键字段
    non_pk_cols = [col for col in df1.columns if col != pk_col]
    
    # 标记存在字段变更的行
    has_change = pd.Series(False, index=df_merged.index)
    for col in non_pk_cols:
        col_old = f"{col}_old"
        col_new = f"{col}_new"
        # 对比新旧值,处理空值相等的情况
        change_mask = ~df_merged[col_old].fillna('').eq(df_merged[col_new].fillna(''))
        has_change = has_change | change_mask
    
    # 筛选出有变更的行,或仅在df2中存在的新增记录
    only_in_df2 = df_merged[[f"{col}_old" for col in non_pk_cols]].isna().all(axis=1)
    df_diff = df_merged[has_change | only_in_df2]
    
    # 保留主键和新值字段,重命名回原字段名
    result_cols = [pk_col] + [f"{col}_new" for col in non_pk_cols]
    df_diff = df_diff[result_cols].rename(columns={f"{col}_new": col for col in non_pk_cols})
    
    return df_diff

代码关键点

  • 用fillna('')统一处理空值,避免两边都是空值时被误判为变更
  • 遍历所有非主键字段,只要有一个字段值不同就标记为需要更新
  • 单独识别新增记录:df1中无匹配主键的行(旧字段全为空)
  • 最终结果只保留df2的新值,结构和原DataFrame完全一致,可直接用于SQL更新操作

测试验证

用示例数据测试:
df1:

IDNameAgeCity
1Alice25NY
2Bob30LA
4Dave35CHI

df2:

IDNameAgeCity
1Alice26NY
3Eve28MIA
4Dave35DAL

调用函数后返回的结果:

IDNameAgeCity
1Alice26NY
3Eve28MIA
4Dave35DAL

完全符合期望输出。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 13:45:37