如何高效对比列结构相同但行数不同的两个pandas DataFrame识别变动
你可以通过pandas外连接合并+自定义标记的方式实现需求,全程采用pandas底层优化的向量化运算,比手动逐行遍历效率高很多,适合大数据量的数据审计场景,具体实现如下:
实现逻辑
- 以
ID+Period作为联合主键对新旧两个DataFrame做外连接,标记每行数据的来源(仅旧表存在、仅新表存在、两表都存在) - 对仅旧表存在的行标记为
Deleted(行删除),仅新表存在的行标记为New(行新增) - 对两表都存在的行,对比指定的
Price和OtherID列,只要有一列值不匹配就标记为Changed(行内容变更) - 过滤出所有有变动的行,整理为要求的输出格式
代码实现
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
相关产品推荐
相关产品推荐

