如何用多进程加速Pandas DataFrame导出至Excel?问题排查
问题分析与解决方案
你的代码为什么没提速?
- 你用了
pool.apply(),这个方法是阻塞式调用单个进程,本质上还是单进程执行,完全没用到多进程的并行能力。 - 直接把整个大DataFrame传给子进程,会触发DataFrame的完整拷贝,反而增加额外开销,拖慢速度。
可行的多进程导出方案
xlsx是单文件结构,无法直接多进程写入同一个工作表,正确思路是分块处理+多进程写入不同工作表/临时文件,最后合并:
方案1:分块写入同一个文件的不同工作表(多进程)
把大DataFrame拆分成多个小DataFrame,每个进程负责写入一个工作表,使用支持追加写入的openpyxl引擎。
示例代码:
import multiprocessing import pandas as pd import numpy as np from openpyxl import load_workbook def _color_red_or_green(val): color = 'red' if val < 0.5 else 'green' return f'color: {color}' def save_chunk_to_sheet(args): chunk_df, sheet_name, output_path = args # 子进程内单独处理样式 styled_df = chunk_df.style.applymap(_color_red_or_green) # 追加写入新工作表 with pd.ExcelWriter(output_path, engine='openpyxl', mode='a', if_sheet_exists='replace') as writer: styled_df.to_excel(writer, sheet_name=sheet_name, index=False) if __name__ == '__main__': # 构造测试数据 merged_df = pd.DataFrame(np.random.rand(173000, 82)) output_file = 'output.xlsx' # 先创建空文件,避免首次写入报错 pd.DataFrame().to_excel(output_file, index=False) # 按CPU核心数拆分数据块 num_chunks = multiprocessing.cpu_count() chunks = np.array_split(merged_df, num_chunks) # 准备每个进程的任务参数 task_args = [(chunks[i], f'Sheet_{i+1}', output_file) for i in range(num_chunks)] # 启动多进程池执行 with multiprocessing.Pool(processes=num_chunks) as pool: pool.map(save_chunk_to_sheet, task_args) print("导出完成")
方案2:多进程写入临时文件,最后合并为单工作表
如果需要所有数据在同一个工作表,可以先让每个进程导出到单独的临时xlsx文件,再用单进程把这些文件的内容合并到同一个工作表中,避免多进程写入冲突。
关键注意事项
- 禁止多进程写入同一工作表:xlsx格式不支持并发写入同一工作表,会导致文件损坏或数据丢失。
- 合理拆分数据块:块大小不宜过小(避免进程切换开销)或过大(失去并行优势),建议按CPU核心数拆分。
- 样式处理放在子进程:不要在主进程处理完样式再传递给子进程,会增加数据拷贝开销,应该在子进程内对每个数据块单独处理样式。
内容的提问来源于stack exchange,提问作者Akshay
相关产品推荐
相关产品推荐

