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

大CSV文件按ID关联合并的高效实现方案咨询

高效处理百万级CSV关联方案

现有代码的核心问题

  • 嵌套循环带来**O(n*m)**的时间复杂度,50万行的两个文件会产生2.5e11次操作,效率必然极低
  • 重复分割line1,做了大量冗余计算
  • file2.remove(line2)是列表删除操作,每次耗时O(m),进一步拖慢速度
  • 逻辑存在错误:无匹配补空列的条件写反,还有字符串转义错误(split(";\")应为split(";"))

优化思路:哈希表快速查找

核心是先把File2的数据加载到字典中,用ID_PERSON作为键,对应的行数据作为值。这样从File1查找匹配项的时间复杂度降到O(1),整体处理时间从O(n*m)降到O(n+m),百万级数据几分钟就能处理完成。

具体实现步骤

  1. 读取File2,构建ID_PERSON到行数据的映射字典
  2. 遍历File1的每一行,根据ID去字典中查找对应数据
  3. 找到匹配则拼接字段写入结果,无匹配则补充对应数量的空列

优化后代码示例

用Python内置csv模块处理,避免手动分割的各种问题(比如字段含分隔符的情况),同时保证效率:

import csv

# 配置文件路径和分隔符
FILE1_PATH = "file1.csv"
FILE2_PATH = "file2.csv"
OUTPUT_PATH = "result.csv"

# 第一步:构建File2的ID映射字典
id_to_file2 = {}
with open(FILE2_PATH, 'r', encoding='utf-8', errors='ignore') as f2:
    reader = csv.reader(f2, delimiter=';')
    # 获取File2的列数,用于后续补空列
    file2_cols = next(reader)
    file2_col_count = len(file2_cols)
    # 重置指针并跳过表头(无表头可注释此行)
    f2.seek(0)
    next(reader)
    for row in reader:
        if len(row) >= 2:  # 确保ID_PERSON列存在
            id_person = row[1].strip()
            id_to_file2[id_person] = row

# 第二步:处理File1并生成结果
with open(FILE1_PATH, 'r', encoding='utf-8', errors='ignore') as f1, \
     open(OUTPUT_PATH, 'w', encoding='utf-8', newline='') as output:
    reader = csv.reader(f1, delimiter='|')
    writer = csv.writer(output, delimiter=';')
    
    # 处理表头(无表头可注释此段)
    header1 = next(reader)
    writer.writerow(header1 + file2_cols)
    
    for row1 in reader:
        if not row1:
            continue
        id_1 = row1[0].strip()
        # 查找匹配行,无匹配则生成空列
        row2 = id_to_file2.get(id_1, [''] * file2_col_count)
        writer.writerow(row1 + row2)

额外优化点

  • 若File2存在一个ID对应多行的情况,可将字典值改为列表存储所有匹配行,处理File1时循环写入多行
  • 若文件过大导致内存不足,可分块处理File2,或用SQLite临时存储数据后做关联查询
  • 指定文件编码避免乱码问题

内容的提问来源于stack exchange,提问作者MicrophoneTrompette

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 14:10:29