Python读取Excel提速方案咨询:多线程与多进程该如何选择?
优化Excel批量处理速度的实用方案
首先,23个工作表、每个1000行就耗时15分钟,确实是读取环节拖了后腿——毕竟Excel文件的读写本身就容易因为低效的库或逻辑变慢。先给你几个优先级从高到低的优化方案,比直接上多线程/多进程见效更快:
1. 换用高效的读取库+只读模式
很多人用openpyxl或xlrd时默认用普通模式,会把整个工作表加载到内存,对于大量数据来说非常慢。改成只读模式可以流式读取,内存占用低且速度提升明显:
用openpyxl只读模式示例
from openpyxl import load_workbook, Workbook def process_single_sheet(source_wb, sheet_name, dest_wb): source_sheet = source_wb[sheet_name] # 只读取首行判断,不用加载全表 header = next(source_sheet.iter_rows(values_only=True)) if "UPDATED" in header: dest_sheet = dest_wb.create_sheet(title=sheet_name) # 流式写入,避免内存过载 for row in source_sheet.iter_rows(values_only=True): dest_sheet.append(row) # 只读模式加载源文件,data_only=True跳过公式直接读值 source_wb = load_workbook("your_source_file.xlsx", read_only=True, data_only=True) dest_wb = Workbook() for sheet_name in source_wb.sheetnames: process_single_sheet(source_wb, sheet_name, dest_wb) # 删除默认生成的空Sheet if "Sheet" in dest_wb.sheetnames: dest_wb.remove(dest_wb["Sheet"]) dest_wb.save("your_output_file.xlsx") source_wb.close()
更推荐:用Pandas批量处理
Pandas底层用C扩展实现,读取Excel的速度比纯Python库快得多,而且代码更简洁:
import pandas as pd # 一次性读取所有工作表,返回字典{表名: DataFrame} all_sheets = pd.read_excel("your_source_file.xlsx", sheet_name=None) # 批量写入符合条件的表 with pd.ExcelWriter("your_output_file.xlsx") as writer: for sheet_name, df in all_sheets.items(): # 检查列名(即原表首行)是否包含"UPDATED" if "UPDATED" in df.columns: df.to_excel(writer, sheet_name=sheet_name, index=False)
用这个方式处理你的数据,应该能把时间压缩到几十秒甚至几秒内。
2. 多线程vs多进程:什么时候用?
如果优化库之后还是有性能瓶颈(比如你的数据量远大于当前规模),再考虑并发处理:
- 多线程更适合你的场景:因为你的瓶颈在IO密集型的文件读取,线程在等待IO时可以切换到其他任务,不会被GIL(全局解释器锁)严重限制。用
concurrent.futures.ThreadPoolExecutor就能轻松实现:
import pandas as pd from concurrent.futures import ThreadPoolExecutor def write_sheet(sheet_name, df, writer): if "UPDATED" in df.columns: df.to_excel(writer, sheet_name=sheet_name, index=False) all_sheets = pd.read_excel("your_source_file.xlsx", sheet_name=None) with pd.ExcelWriter("your_output_file.xlsx") as writer: # 线程数建议设为CPU核数的2-4倍,或根据实际情况调整 with ThreadPoolExecutor(max_workers=4) as executor: futures = [executor.submit(write_sheet, name, df, writer) for name, df in all_sheets.items()] for future in futures: future.result()
- 多进程更适合CPU密集型任务(比如大量数据清洗、计算),但对于你的读取场景,多进程的开销(比如进程间通信、文件锁)反而可能拖慢速度,所以优先级低于多线程。
3. 额外小技巧
- 跳过不需要的表:先遍历所有表名,读取每个表的首行判断,不满足条件的直接跳过,避免读取整表的开销。
- 关闭不必要的功能:比如用
data_only=True跳过公式计算,直接读取单元格的值;避免加载格式、图表等无关内容。
内容的提问来源于stack exchange,提问作者KnakworstKoning
相关产品推荐
相关产品推荐

