Pandas DataFrame查找for循环不终止 2000万行数据匹配效率问题
问题诊断
1. 逻辑错误
你的代码存在缩进错误:break语句和if判断同级,没有缩进至if代码块内部,无论是否匹配到对应值,内层循环都会在第一次迭代后直接终止,只会检查表2的第一行数据,绝大多数匹配请求都会失败,逻辑本身不符合需求。
2. 效率问题
即使修正缩进问题,代码也完全无法支撑2000万行的数据规模:
- 双重
for循环的时间复杂度为O(N*M),其中N是表1总数据量(2000万行),M是表2的行数,运算量会达到千亿级别,这是运行8小时无法结束的核心原因。 - 每次处理完单个文件就调用
pd.concat拼接总表,会频繁触发全量数据内存拷贝,进一步放大性能损耗。
解决方案
用pandas内置的向量化操作替代手动循环,匹配过程基于哈希表实现,时间复杂度仅为O(N+M),性能是手动循环的上千倍。
优化后代码
import pandas as pd # 提前预处理参照表,只保留需要的列 Table2 = Table2[["B", "C", "D"]] # 用列表暂存每个文件的处理结果,避免频繁concat res_list = [] for f in all_files: table1 = pd.read_csv(all_files[f]) # 左连接匹配,保留表1所有行,自动匹配C、D列 table1 = table1.merge(Table2, on="B", how="left") res_list.append(table1) # 最后一次性合并所有结果 df = pd.concat(res_list, axis=0, ignore_index=True)
额外优化建议
如果内存有限,无法一次性存储所有处理结果,可以处理完单个文件后直接追加写入输出CSV,不需要暂存在列表中;如果表2规模较小,还可以提前生成映射字典进一步提速:
# 提前生成B列到C、D的映射字典 c_map = Table2.set_index("B")["C"].to_dict() d_map = Table2.set_index("B")["D"].to_dict() # 单个文件处理时直接映射 table1["C"] = table1["B"].map(c_map) table1["D"] = table1["B"].map(d_map)
内容的提问来源于stack exchange,提问作者el-cheapo
相关产品推荐
相关产品推荐

