如何对比含同一键多条记录的两个DataFrame?
多记录分组DataFrame对比实现方案
你需要对比两个包含多记录分组(同一product_name对应多条数据)的DataFrame,csv_diff的compare方法因依赖唯一键无法满足需求,这里用Pandas实现自定义对比逻辑,生成指定格式的变更汇总。
实现步骤
1. 读取并预处理数据
先将CSV文件读取为Pandas DataFrame,统一列名避免空格带来的操作麻烦:
import pandas as pd # 读取CSV文件 df1 = pd.read_csv("df1.csv") df2 = pd.read_csv("df2.csv") # 重命名含空格的列名,方便后续操作 df1.rename(columns={"product name": "product_name"}, inplace=True) df2.rename(columns={"product name": "product_name"}, inplace=True)
2. 对比共同产品的记录差异
针对两个DataFrame共有的product_name,按顺序对比对应行的字段值,收集差异:
changes = [] # 获取两个DataFrame共有的产品名称 common_products = set(df1["product_name"]) & set(df2["product_name"]) for prod in common_products: # 提取当前产品的所有记录,重置索引确保顺序对应 df1_records = df1[df1["product_name"] == prod].reset_index(drop=True) df2_records = df2[df2["product_name"] == prod].reset_index(drop=True) # 取两者行数的最小值,避免索引越界 min_row_count = min(len(df1_records), len(df2_records)) prod_diff = {} # 遍历每个字段(跳过产品名称列) for col in df1_records.columns: if col == "product_name": continue # 收集当前字段所有行的差异值对 field_diffs = [] for i in range(min_row_count): val_old = df1_records.loc[i, col] val_new = df2_records.loc[i, col] if val_old != val_new: field_diffs.append([val_old, val_new]) if field_diffs: prod_diff[col] = field_diffs # 如果当前产品存在差异,添加到结果列表 if prod_diff: changes.append({ "key": prod, "changes": prod_diff }) # 输出结果 print("changes:") print(changes)
3. 可选:新增/删除产品的记录补充
如果需要统计仅在df2存在的新增产品,或仅在df1存在的删除产品记录,可以添加以下代码:
# 处理新增产品 added_products = set(df2["product_name"]) - set(df1["product_name"]) for prod in added_products: changes.append({ "key": prod, "type": "added", "records": df2[df2["product_name"] == prod].to_dict("records") }) # 处理删除产品 removed_products = set(df1["product_name"]) - set(df2["product_name"]) for prod in removed_products: changes.append({ "key": prod, "type": "removed", "records": df1[df1["product_name"] == prod].to_dict("records") })
方案优势
- 完全基于Pandas原生功能,无需依赖第三方库的限制
- 自定义对比逻辑,适配多记录分组的场景
- 可灵活扩展新增/删除产品的统计需求
内容的提问来源于stack exchange,提问作者kitten_world
相关产品推荐
相关产品推荐

