优化多CSV文件合并效率的技术咨询
优化多CSV文件合并效率的技术咨询
看起来你现在的问题是处理大量小CSV文件时,用pandas逐个读取存列表再concat的速度太慢——完全能理解,毕竟每个小文件都生成一个DataFrame,来回折腾元数据确实会有不少额外开销,尤其是当文件数量多的时候。结合你说的场景(每个CSV是6列5行、表头一致、每8个合并一次做后续分析),我给你几个实用的优化方向:
一、减少DataFrame创建的开销(最直接的优化)
你现在每个小文件都生成一个DataFrame,再把这些小DF堆进列表最后concat,其实对这么小的文件来说,DataFrame的初始化开销占比很高。不如换个思路:用轻量的csv模块先把所有数据行收集起来,最后一次性生成DataFrame,这样只创建一次DF,省掉很多重复操作。
举个代码例子:
import os import csv import pandas as pd # 第一步:先把所有要处理的CSV路径收集好,按8个一组划分 csv_files = [] for root, _, files in os.walk("你的根目录路径"): for file in files: if file.endswith(".csv"): csv_files.append(os.path.join(root, file)) # 按每8个文件一组处理 for group_idx in range(0, len(csv_files), 8): current_group = csv_files[group_idx:group_idx+8] all_data_rows = [] target_header = None for file_path in current_group: with open(file_path, 'r', newline='') as f: # 用csv阅读器读取,指定分隔符是制表符 reader = csv.reader(f, delimiter='\t') # 读取表头:只保留第一份表头,后面的文件跳过表头 header = next(reader) if target_header is None: target_header = header # 把当前文件的所有数据行加进去 all_data_rows.extend(list(reader)) # 一次性生成合并后的DataFrame combined_df = pd.DataFrame(all_data_rows, columns=target_header) # 保存成新的CSV(或者直接用于后续分析) combined_df.to_csv(f"合并组_{group_idx//8 + 1}.csv", index=False, sep='\t')
二、优化pandas读取的参数(如果还是想用pandas读取)
如果你习惯用pandas,那可以通过指定参数减少读取时的开销:
- 指定
dtype参数:告诉pandas每列的数据类型,避免它自动推断(这步能省不少时间) - 对非第一个文件跳过表头:因为所有文件表头一致,后面7个文件用
header=None,然后指定列名
示例代码:
import os import pandas as pd csv_files = [] for root, _, files in os.walk("你的根目录路径"): for file in files: if file.endswith(".csv"): csv_files.append(os.path.join(root, file)) # 假设你知道列的类型,比如都是float(根据你的实际情况调整) dtype_map = { "MSE": float, "RMSE": float, "MAE": float, # 补充剩下的3列类型 } for group_idx in range(0, len(csv_files), 8): current_group = csv_files[group_idx:group_idx+8] df_list = [] # 读取第一个文件,保留表头 first_df = pd.read_csv(current_group[0], sep='\t', dtype=dtype_map) df_list.append(first_df) # 读取剩下的7个文件,跳过表头 for file_path in current_group[1:]: df = pd.read_csv(file_path, sep='\t', header=None, names=first_df.columns, dtype=dtype_map) df_list.append(df) # 合并 combined_df = pd.concat(df_list, ignore_index=True) combined_df.to_csv(f"合并组_{group_idx//8 + 1}.csv", index=False, sep='\t')
三、其他小技巧
- 尽量避免在循环里做
pd.concat:你之前的代码是把所有DF都存到列表最后一次性concat,这其实已经是pandas里推荐的方式了,但问题出在小文件太多导致的DF数量太多——所以按8个一组分批处理,处理完一组就清空列表,也能减少内存占用,间接提升速度。 - 不要用
os.walk的时候实时处理:先把所有文件路径收集好再分组,比边遍历边处理更清晰,也方便你做异常处理(比如某组不够8个文件的情况)。
备注:内容来源于stack exchange,提问作者Maor Barzilay
相关产品推荐
相关产品推荐

