pandas.read_excel()读大文件慢是因默认执行解压、xml解析、样式重建、类型推断等全套操作;openpyxl的read_only=true可绕过dom构建,配合iter_rows(values_only=true)流式读取,节省约70%时间。

pandas.read_excel() 读大文件慢,不是你代码写得差,是它默认干了太多事。
它会把整个 .xlsx 解压、逐个 XML 文件解析、重建样式表、加载共享字符串、推断每列类型、再塞进 DataFrame —— 这些操作加起来,50MB 文件花 2 分钟真不奇怪。
openpyxl 的 read_only=True 能省掉 70% 时间
read_only=True 不是“加速开关”,而是彻底绕开 DOM 树构建:不加载样式、不解析公式、不缓存空行、不维护单元格对象,只按需流式读取原始值。
- 必须搭配
iter_rows(values_only=True)使用,否则仍会返回带格式的Cell对象 - 不能写入、不能访问
cell.font或cell.fill等属性 - 读完必须调用
wb.close(),否则文件句柄不释放,Windows 下可能锁死文件 - 对含大量空行或合并单元格的表,
iter_rows()仍会遍历所有行号(包括空行),建议先用 Excel 手动删空行再处理
from openpyxl import load_workbook
wb = load_workbook('huge.xlsx', read_only=True)
ws = wb.active
for row in ws.iter_rows(values_only=True):
# row 是 tuple,不是 list;None 表示空单元格
if row[0] is not None: # 跳过全空行
process(row)
wb.close()
pandas.read_excel(chunksize=) 容易踩内存坑
chunksize 看似分块,但底层仍用 openpyxl 全量加载工作表结构 —— 表头、样式、空行信息全在内存里,只是数据行被切片。
- 实测:1GB 文件设
chunksize=10000,内存峰值仍达 3.2GB(非线性下降) -
usecols必须配合使用,否则每块仍加载全部列 -
dtype建议显式指定,比如{'id': 'int32', 'amount': 'float32'},避免每块重复类型推断 - 不要直接
pd.concat(chunks),会瞬间吃光内存;应边读边存(如写 CSV / 数据库)
导出百万行时 to_excel() 卡住?别硬扛
to_excel() 本质是逐单元格生成 XML + ZIP 打包,CPU 软编码 + 频繁 IO,100 万行常卡死或触发 MemoryError。
-
to_parquet()是真正替代方案:列式二进制,100 万行 1–3 秒,体积小一半,pd.read_parquet()还支持列裁剪 - 用
pyarrow引擎(pip install pyarrow),别用fastparquet,后者对datetime和 nullable 类型支持弱 - 如果业务方坚持要
.xlsx,就只在最后一步转:“查出 10 万行结果 → 写 Excel”,而不是“全量数据 → to_excel”
关键点不在“选哪个库”,而在于承认 Excel 格式本身不适合大数据流转。真正快的方案,往往是绕开 Excel —— 把它当交付终点,而不是处理中间态。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











