如何用Pandas比较两个DataFrame多列并标记差异列名
为Pandas新DataFrame添加变更原因列(兼容新增行)
需求:对比两个Pandas DataFrame的qty1、qty2列,为新DataFrame添加update_reason列,记录发生变更的列名,同时兼容新增行的场景。
示例数据与期望输出
示例代码
import pandas as pd # 旧数据 data_list1 = [[1, "p1", 10.0, 20.0],[2, "p2", 15.0, 25.0],[3, "p3", 20.0, 30.0]] df1 = pd.DataFrame(data_list1, columns=['id', 'p_name', 'qty1', 'qty2']) # 新数据 data_list2 = [[1, "p1", 12.0, 22.0],[2, "p2", 16.0, 25.0],[3, "p3", 20.0, 34.0], [4, "p4", 32.0, 32.0]] df2 = pd.DataFrame(data_list2, columns=['id', 'p_name', 'qty1', 'qty2']) print("旧数据df1:") print(df1) print("\n新数据df2:") print(df2)
输入1(旧数据df1)
id p_name qty1 qty2 0 1 p1 10.0 20.0 1 2 p2 15.0 25.0 2 3 p3 20.0 30.0
输入2(新数据df2)
id p_name qty1 qty2 0 1 p1 12.0 22.0 1 2 p2 16.0 25.0 2 3 p3 20.0 34.0 3 4 p4 32.0 32.0
期望输出
id p_name qty1 qty2 update_reason 0 1 p1 12.0 22.0 qty1,qty2 1 2 p2 16.0 25.0 qty1 2 3 p3 20.0 34.0 qty2 3 4 p4 32.0 32.0
解决方案代码
import pandas as pd # 加载数据 data_list1 = [[1, "p1", 10.0, 20.0],[2, "p2", 15.0, 25.0],[3, "p3", 20.0, 30.0]] df1 = pd.DataFrame(data_list1, columns=['id', 'p_name', 'qty1', 'qty2']) data_list2 = [[1, "p1", 12.0, 22.0],[2, "p2", 16.0, 25.0],[3, "p3", 20.0, 34.0], [4, "p4", 32.0, 32.0]] df2 = pd.DataFrame(data_list2, columns=['id', 'p_name', 'qty1', 'qty2']) # 以id为键合并新旧数据,保留新数据所有行 merged = df2.merge(df1, on='id', suffixes=('_new', '_old'), how='left') # 初始化变更原因为空字符串 df2['update_reason'] = '' # 标记qty1列的变更 mask_qty1 = merged['qty1_new'] != merged['qty1_old'] df2.loc[mask_qty1, 'update_reason'] += 'qty1,' # 标记qty2列的变更 mask_qty2 = merged['qty2_new'] != merged['qty2_old'] df2.loc[mask_qty2, 'update_reason'] += 'qty2,' # 清理末尾多余的逗号 df2['update_reason'] = df2['update_reason'].str.rstrip(',') print(df2)
代码说明
- 合并数据:通过
merge以id为关联键做左连接,确保新数据的所有行都被保留,用后缀区分新旧列。 - 标记变更:分别对比
qty1、qty2的新旧值,将变更的列名追加到update_reason字段。 - 格式清理:用
str.rstrip(',')去除字段末尾多余的逗号,新增行因旧值为NaN,对比后不会追加内容,保持空字符串。
内容的提问来源于stack exchange,提问作者Shankar
相关产品推荐
相关产品推荐

