大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),百万级数据几分钟就能处理完成。
具体实现步骤
- 读取File2,构建
ID_PERSON到行数据的映射字典 - 遍历File1的每一行,根据
ID去字典中查找对应数据 - 找到匹配则拼接字段写入结果,无匹配则补充对应数量的空列
优化后代码示例
用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
相关产品推荐
相关产品推荐

