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

基于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

解决方案步骤

  1. 读取CSV文件:用pandas.read_csv加载两个文件,注意根据实际分隔符调整参数
  2. 内连接合并:基于id列做内连接,保留共同行,自动给重复列加上_old/_new后缀
  3. 遍历对比列对:对每一组同名列,对比值的差异,整理成old值, new值的格式;对仅存在于单个文件的列,标注NaN
  4. 整理结果格式:重命名列,保留原列名,将对比结果填充到对应列,最后输出到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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 16:47:10