如何通过多线程/多进程并发执行to_csv并行导出DataFrame到CSV
方案结论
多个独立DataFrame分别写入不同CSV文件属于典型IO密集型场景,完全可以通过并发提升导出速度,优先选择多线程方案,不推荐多进程。
核心原因:pandas的to_csv底层走C实现的磁盘写入逻辑,执行时会释放Python全局解释器锁(GIL),多线程可以实现真正的并行IO,且没有多进程场景下DataFrame序列化、跨进程传输的额外开销,在这个场景下投入产出比最高。
你原有代码存在大量重复判断逻辑,可以先把所有待导出对象和对应文件名做统一映射,减少冗余代码。
多线程并发导出实现代码
from concurrent.futures import ThreadPoolExecutor, as_completed import pandas as pd # 统一整理所有待导出DataFrame和对应目标文件名 export_task_list = [ (isd, "Issuedate.csv"), (ind, "Inceptiondate.csv"), # 注:原代码此处文件名遗漏了后缀分隔点,已修正 (exd, "Expirydate.csv"), (psd, "policystatedate.csv"), (visd, "vehicleissuedate.csv"), (vind, "vehicleinceptiondate.csv"), (vexd, "vehicleexpirydate.csv"), (sd, "statusdate.csv"), (ise, "istemarhexpiry.csv"), (idb, "insureddateofbirth.csv"), (mdd, "maindriverdob.csv"), (add, "adddriverdob.csv") ] # 提前过滤空DataFrame,避免生成无意义的空文件 valid_tasks = [item for item in export_task_list if len(item[0]) != 0] def single_export(df: pd.DataFrame, file_name: str) -> str: # 可根据需要在to_csv中加参数,比如index=False不导出行索引、encoding='utf-8-sig'解决Excel乱码 df.to_csv(file_name, index=False) return f"导出完成: {file_name}" if __name__ == "__main__": # 线程数不要设置过高:机械硬盘建议设为4,NVMe固态硬盘可设为8-16,过高并发会因磁盘寻址开销增大反而降速 with ThreadPoolExecutor(max_workers=4) as executor: task_futures = [executor.submit(single_export, df, fname) for df, fname in valid_tasks] for future in as_completed(task_futures): print(future.result())
不推荐多进程的原因
- 多进程更适配CPU密集型场景(比如大规模数值计算、数据转换加工),对IO密集型场景收益极低
- 多进程启动成本远高于线程,且大体积DataFrame跨进程传输需要做序列化/反序列化,额外开销甚至可能超过并发带来的速度提升,最终导出速度比串行还慢
- 你的导出任务总量只有十几个,完全没必要承担多进程的额外复杂度
注意事项
- 所有并发写入必须是不同的目标文件,绝对不要让多个线程/进程同时写同一个文件,会出现文件损坏、内容错乱的问题,你的现有逻辑是每个DataFrame写独立文件,不存在锁冲突问题
- 如果使用Windows系统,必须把线程池启动逻辑放在
if __name__ == "__main__":代码块下,否则会出现递归启动线程的报错 - 如果导出的CSV需要用Excel打开,建议在
to_csv中加入encoding='utf-8-sig'参数,避免中文乱码
内容的提问来源于stack exchange,提问作者Saad Saleem
相关产品推荐
相关产品推荐

