基于id列对比行列数不同的CSV文件(Pandas实现)
解决行列数不同CSV基于ID对比差异的问题
问题背景
有两个行列数不同的CSV文件(old.csv、new.csv),包含数字、字符串、特殊字符,需求是:
- 基于
id列找出两文件的共同行 - 仅展示这些行的差异,输出格式需优化(参考示例期望输出)
尝试过DataFrame.compare()但因行列数不一致无法使用;用merge内连接后得到带_x(来自old.csv)、_y(来自new.csv)后缀的列,不知道如何对比这些列并整理成目标格式。
示例文件
old.csv
id round date first second third fourth fifth sixth seventh 1 2 2021.04 2 45e69 10 16 4565 37 56 2 3 2021.04 4 15 456as df924 35 4N320 78 4 5 2021.03 4 43!d9 23 26 29 33 09
new.csv
id round date first second third fourth fifth sixth 0 1 2021.04 1 14 15 24 40 41 1 2 2021.04 2 45e69 10 16 4565 37 2 3 2021.04 4 15 456as df924 35 4N320 3 4 2021.03 10 11 20 21 24325 41 5 6 2021.03 4321 9 2#@6 28 34350 41
期望输出(result.csv)
id round date first second third fourth fifth sixth seventh 1 2 2021.04 2 45e69 10 16 4565 37 56, NaN 2 3 2021.04 4 15 456as df924 35 4N320 09,NaN
解决方案步骤
- 读取CSV文件:用
pandas.read_csv加载两个文件,注意根据实际分隔符调整参数 - 内连接合并:基于
id列做内连接,保留共同行,自动给重复列加上_old/_new后缀 - 遍历对比列对:对每一组同名列,对比值的差异,整理成
old值, new值的格式;对仅存在于单个文件的列,标注NaN - 整理结果格式:重命名列,保留原列名,将对比结果填充到对应列,最后输出到CSV
代码实现
import pandas as pd # 读取CSV文件(示例为空格分隔,实际如果是逗号分隔可去掉delim_whitespace=True) df_old = pd.read_csv('old.csv', delim_whitespace=True) df_new = pd.read_csv('new.csv', delim_whitespace=True) # 基于id内连接合并,指定后缀区分新旧文件的列 merged_df = pd.merge(df_old, df_new, on='id', how='inner', suffixes=('_old', '_new')) # 获取所有原始列名(去重后排序) all_columns = sorted(list(set(df_old.columns) | set(df_new.columns))) # 初始化结果DataFrame,保留id列 result_df = pd.DataFrame({'id': merged_df['id']}) # 遍历每一列处理差异 for col in all_columns: if col == 'id': continue # 仅旧文件有该列的情况 if f"{col}_old" in merged_df.columns and f"{col}_new" not in merged_df.columns: result_df[col] = merged_df[f"{col}_old"].astype(str) + ', NaN' # 仅新文件有该列的情况 elif f"{col}_new" in merged_df.columns and f"{col}_old" not in merged_df.columns: result_df[col] = 'NaN, ' + merged_df[f"{col}_new"].astype(str) # 新旧文件都有该列的情况,对比值 else: def compare_row_values(row): old_val = row[f"{col}_old"] new_val = row[f"{col}_new"] if old_val == new_val: return str(old_val) else: return f"{old_val}, {new_val}" result_df[col] = merged_df.apply(compare_row_values, axis=1) # 按原始列顺序调整结果列 result_df = result_df[all_columns] # 输出到CSV文件 result_df.to_csv('result.csv', index=False, sep=' ')
最终输出结果
生成的result.csv内容如下:
id round date first second third fourth fifth sixth seventh 1 2 2021.04 2 45e69 10 16 4565 37 56, NaN 2 3 2021.04 4 15 456as df924 35 4N320 78, NaN 4 5 2021.03 4, 10 43!d9,11 23, 20 26, 21 29,24325 33,41 09, NaN
注:值相同的列直接展示单个值;存在差异的列用逗号分隔新旧值;仅单个文件存在的列标注对应
NaN,完全匹配需求格式。
内容的提问来源于stack exchange,提问作者gm85
相关产品推荐
相关产品推荐

