ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Python读取10万行Excel性能对比:openpyxl、pandas、calamine谁最快?

Python读取10万行Excel性能对比:openpyxl、pandas、calamine谁最快? 如果你处理过“超过 3 万行的 Excel”大概率遇到过这类情况打开文件要等好几秒筛选一下又卡住公式重算一次能去倒杯水。而一旦数据量来到 10 万行很多常规工具已经开始濒临“不可用”的边缘。于是不少人会转向 Python想用脚本批量处理 Excel。但紧接着又一个问题冒出来了Python 里读 Excel 的库实在太多了pandas、openpyxl、xlrd、pyxlsb、calamine……到底该用哪个同样是读一个 10 万行的 Excel 文件不同库的耗时差距可能不是百分之几而是好几倍甚至十几倍。这篇文章就来做一个可复现的基准测试用 Python 常见库分别读取一个 10 万行、20 列的 Excel 文件对比它们在读取耗时、内存占用、易用性和适用场景上的差异。文章里会给出一套完整的测试脚本包括测试数据生成、耗时统计、内存观察和结果记录表方便你直接在自己的机器上跑一遍得到属于你自己的横向对比数据。1. 核心结论速览先说明一点以下结论是基于常见 Excel 解析库的实现原理和一般项目表现的推测具体耗时数据必须由你在本机跑完测试脚本后填写。CPU 型号、磁盘类型、Python 版本、Excel 文件版本都会影响结果所以更稳妥的做法是把本文当成一套测试方法论跑完再把数据记进表格里。从库的底层实现来看有几个比较稳定的规律对比维度pandas openpyxlpandas xlrdopenpyxl 直接读xlrd 直接读python-calaminepolars calamine读取 xlsx常用但 openpyxl 是纯 Python 解析偏慢不支持 xlsxxlrd 2.x 只支持 xls支持有 read_only 模式仅 xls支持Rust 实现通常更快支持Flow 式读取通常更快读取 xls依赖 xlrd 引擎时可用支持不支持支持支持支持API 易用性高直接出 DataFrame高中等面向单元格中等面向单元格中等返回 list/迭代器高出 DataFrame内存占用偏高偏高普通模式偏高read_only 较低普通模式偏高较低较低适合场景数据分析、清洗、建模老版 .xls 数据改样式、写公式、读部分单元格老版 .xls 数据高性能纯读取高性能 大规模数据处理是否需要装额外引擎需要需要独立库独立库独立库polars 内建从材料中可以确认的通用知识openpyxl 底层是通过解析 XML 实现的纯 Python 库性能上限受语言本身限制。xlrd 2.0 之后移除了对 xlsx 的支持只保留 xls。python-calamine 是对 Rust 库 calamine 的封装天生比纯 Python 解析更有性能优势。pandas 读取 Excel 离不开底层引擎pd.read_excel()只是套了一层壳。读取大文件时pandas 内部还会做 DataFrame 构建即使底层引擎解析得再快pandas 这层也会产生额外开销。2. 适用场景与测试边界这个测试不是要证明“哪个库天下第一”而是帮你回答 4 个问题项目里只是偶尔读一次 Excel优先考虑哪个库每天要批量处理几十个 10 万行 Excel优先考虑哪个库读取之后还要做复杂的数据过滤、分组、透视优先考虑哪个库机器内存只有 8G甚至更小优先考虑哪个库这 4 个问题的答案并不完全相同。场景推荐方向原因偶尔读取代码量越少越好pandas生态成熟一行读取后续处理方便高频读取追求极限速度polars calamine / python-calamineRust 解析引擎通常明显快于纯 Python需要保留公式、单元格样式openpyxl它是少数能处理公式和样式的库只处理老版 .xlsxlrd针对 xls 格式支持稳定对内存占用敏感openpyxl read_only / polars内存占用通常要低一些大量 Excel 转 CSV 或入库polars读取后可直接写 Parquet/CSV衔接批量任务测试边界也要说清楚这轮测试只测“读取”不测写入、公式计算和样式修改。测试文件统一是二维表结构没有合并单元格、没有图片、没有复杂公式。Excel 文件本身是 xlsx 格式如果换 xls、xlsb结果会完全不同。耗时统计不包含“Python 解释器启动时间”和“import 库的时间”。如果你需要处理的是大量包含公式、复杂样式、合并单元格的“报表型 Excel”那 openpyxl 基本上是唯一选择性能和易用性的权衡要单独考虑。如果要做的是“把 Excel 里的数据抽出来做分析或入库”那高性能读取库更有优势。此外还要提一句合规边界测试用的 Excel 数据建议使用自己生成的模拟数据不要用未经授权的业务数据、个人隐私数据或版权保护的表格文件做公开基准测试。处理真实业务数据前务必确认数据来源合法、授权清晰。3. 环境准备与前置条件这个基准测试对环境要求不高基本都是常规 Python 数据分析环境。3.1 基础环境检查清单检查项建议操作系统Windows 10/11、Ubuntu 20.04、macOS 均可Python 版本3.9 以上推荐 3.10 或 3.11磁盘空间预留 500MB用于安装库和存放测试文件内存建议 8G 以上如果机器只有 4G建议关闭其他大型软件再跑Excel 文件版本统一生成 .xlsx避免版本差异干扰3.2 安装 Python 依赖库推荐先创建一个虚拟环境避免把库装到系统 Python 里污染环境。项目目录可以叫excel_benchmark。mkdir excel_benchmark cd excel_benchmark python -m venv venv # Windows 激活虚拟环境 venv\Scripts\activate # Linux/macOS 激活虚拟环境 source venv/bin/activate激活虚拟环境后安装测试所需的库pip install pandas openpyxl xlrd python-calamine polars如果网络下载慢可以使用国内镜像源安装pip install pandas openpyxl xlrd python-calamine polars -i https://pypi.tuna.tsinghua.edu.cn/simple各库的角色说明pandas最常用的数据处理库read_excel()需要引擎。openpyxl既可以作为 pandas 引擎也可以独立读取 xlsx。xlrd老牌 xls 读取库2.x 版本不再支持 xlsx。python-calamine对 calamine 的 Python 封装专注高性能读取。polars新一代 DataFrame 库自带 calamine 引擎读取 Excel 的能力。安装完成后可以用一行代码验证环境python -c import pandas, openpyxl, xlrd, polars; print(env ok)如果你在import pandas时遇到报错大概率是 pandas 版本与 Python 版本不匹配建议先确认 Python 版本再重新安装。4. 生成 10 万行测试数据没有真实的 10 万行 Excel任何对比都是空谈。第一步先用 Python 生成一份标准测试文件。这个文件包含 10 万行、20 列。列的类型尽量接近真实数据id整数主键name字符串category字符串枚举值value1浮点数value2浮点数其余列整数或字符串生成时采用 pandas openpyxl 引擎写入用to_excel()一条龙完成。注意要让文件尽量“干净”不要包含复杂公式和合并单元格否则后续测试变量不可控。import pandas as pd import numpy as np # 固定随机种子保证每次生成的文件一致 rng np.random.default_rng(42) row_count 100_000 col_count 20 data { id: range(row_count), name: [fuser_{i} for i in range(row_count)], category: rng.choice([A, B, C, D], sizerow_count).tolist(), value1: rng.random(row_count).tolist(), value2: rng.integers(0, 10000, sizerow_count).tolist(), } # 补充更多列凑成 20 列 for i in range(3, col_count): if i % 2 0: data[fint_col_{i}] rng.integers(0, 1000, sizerow_count).tolist() else: data[ffloat_col_{i}] rng.random(row_count).tolist() df pd.DataFrame(data) # 保存为 xlsx output_path test_100k_rows.xlsx df.to_excel(output_path, indexFalse, engineopenpyxl) print(f生成完成{output_path}) print(fShape: {df.shape})运行后目录下应该生成一个test_100k_rows.xlsx大小一般在 15MB 到 30MB 之间具体大小取决于随机字符串和浮点数的长度。这个文件就是后续测试的统一基准。再确认一下读取到的内容是否符合预期可以单独跑一段快速检查import pandas as pd df_check pd.read_excel(test_100k_rows.xlsx, engineopenpyxl, nrows5) print(df_check.head()) print(df_check.shape)这里nrows5只是为了快速预览实际测试不要加这个参数。5. 各库读取耗时测试方法5.1 统一测量方法性能测试最怕统计误差。要尽量做到下面 4 点同一个测试脚本里按顺序读取同一个文件。每个库都连续跑多次比如 5 次取中位数或最小值。文件最好放在本地固态硬盘上避免网络盘和机械盘的干扰。测试过程中不要手动打开 Excel、浏览器等占内存的大软件。Python 里常用的计时方式是time.perf_counter()它是专门用来测量短时间间隔的高精度计时器import time start time.perf_counter() # 待测代码 end time.perf_counter() print(f耗时: {end - start:.4f} 秒)5.2 测试方案一pandas openpyxlpandas 默认的 Excel 引擎之一是 openpyxl这也是目前最常用的方式。但用 openpyxl 引擎时pandas 会先把整个工作表读进内存再构建 DataFrame所以它通常偏慢且占内存较高。import time import pandas as pd def test_pandas_openpyxl(file_path, repeat3): times [] for _ in range(repeat): start time.perf_counter() df pd.read_excel(file_path, engineopenpyxl) cost time.perf_counter() - start times.append(cost) return df.shape, min(times), sum(times) / len(times) file_path test_100k_rows.xlsx shape, min_cost, avg_cost test_pandas_openpyxl(file_path, repeat3) print(fpandasopenpyxl shape{shape}) print(f最短耗时: {min_cost:.4f}s平均耗时: {avg_cost:.4f}s)记录时填写库组合最短耗时平均耗时Shapepandas openpyxl待填待填(100000, 20)5.3 测试方案二pandas xlrd要说明的是xlrd2.x 只能读.xls格式不能读.xlsx。如果你想测试.xls文件的读取需要先把文件另存为.xls或者单独生成一份.xls测试文件。生成.xls文件时不能用 openpyxl 引擎因为 openpyxl 不支持 xls。可以换 xlwt 或直接使用 LibreOffice 转换。如果你手头只有 xlsx 文件可以直接跳过这一组测试不影响整体对比。如果你已经准备好了test_100k_rows.xls可以这样测import time import pandas as pd def test_pandas_xlrd(file_path, repeat3): times [] for _ in range(repeat): start time.perf_counter() df pd.read_excel(file_path, enginexlrd) cost time.perf_counter() - start times.append(cost) return df.shape, min(times), sum(times) / len(times) file_path test_100k_rows.xls shape, min_cost, avg_cost test_pandas_xlrd(file_path, repeat3) print(fpandasxlrd shape{shape}) print(f最短耗时: {min_cost:.4f}s平均耗时: {avg_cost:.4f}s)5.4 测试方案三openpyxl 原生 read_onlyopenpyxl 原生 API 和 pandas 不同它返回的是Worksheet对象需要自己遍历行。openpyxl 的一个重要特性是read_only模式。普通模式下openpyxl 会把所有单元格对象都创建出来非常占内存read_onlyTrue时它按行流式读取能显著降低内存占用速度也可能更快。适合只读不改的场景。import time from openpyxl import load_workbook def test_openpyxl_raw(file_path, read_onlyTrue, repeat3): times [] for _ in range(repeat): start time.perf_counter() wb load_workbook(file_path, read_onlyread_only, data_onlyTrue) ws wb.active row_count 0 for row in ws.iter_rows(values_onlyTrue): row_count 1 wb.close() cost time.perf_counter() - start times.append(cost) return row_count, min(times), sum(times) / len(times) file_path test_100k_rows.xlsx row_count, min_cost, avg_cost test_openpyxl_raw(file_path, read_onlyTrue, repeat3) print(fopenpyxl read_only 行数: {row_count}) print(f最短耗时: {min_cost:.4f}s平均耗时: {avg_cost:.4f}s)如果一开始没有wb.close()windows 下偶尔会出现文件被占用的问题。使用read_onlyTrue时官方推荐遍历完就关闭 workbook。5.5 测试方案四openpyxl 普通模式把read_only改为False就可以测试普通模式row_count, min_cost, avg_cost test_openpyxl_raw( file_path, read_onlyFalse, repeat3 )普通模式更容易复现“内存爆掉”的问题如果你的机器内存只有 8G建议先跑 read_only再决定是否跑普通模式。5.6 测试方案五python-calaminepython-calamine 是 calamine 的 Python 绑定。calamine 是用 Rust 写的 Excel 解析库支持 xlsx、xls、xlsb 等格式因为省去了 Python 层的大量对象构建读取速度在多数场景下会非常快。import time from python_calamine import CalamineWorkbook def test_calamine(file_path, repeat3): times [] for _ in range(repeat): start time.perf_counter() workbook CalamineWorkbook.from_path(file_path) sheet workbook.get_sheet_by_index(0) rows sheet.to_python() cost time.perf_counter() - start times.append(cost) return len(rows), min(times), sum(times) / len(times) file_path test_100k_rows.xlsx row_count, min_cost, avg_cost test_calamine(file_path, repeat3) print(fpython-calamine 行数: {row_count}) print(f最短耗时: {min_cost:.4f}s平均耗时: {avg_cost:.4f}s)如果to_python()报错或者内存占用过猛也可以改用to_pandas()它会直接把数据转成 pandas DataFrame。不过这一步本身也要时间测试时要明确你统计的是“从文件读取并转成 Python 对象”的完整时间。5.7 测试方案六polars calamine 引擎polars 从某些版本开始内置了 calamine 读取 Excel 的能力。polars 的优点是读取后可以直接进入高性能 DataFrame 阶段后续做 group by、join、filter 都比 pandas 更有优势而且它整体的内存控制策略也比 pandas 更现代化。import time import polars as pl def test_polars_calamine(file_path, repeat3): times [] for _ in range(repeat): start time.perf_counter() df pl.read_excel(file_path, enginecalamine) cost time.perf_counter() - start times.append(cost) return df.shape, min(times), sum(times) / len(times) file_path test_100k_rows.xlsx shape, min_cost, avg_cost test_polars_calamine(file_path, repeat3) print(fpolarscalamine shape{shape}) print(f最短耗时: {min_cost:.4f}s平均耗时: {avg_cost:.4f}s)不同版本的 polars 对engine参数的写法可能有差异如果你的版本不稳定可以先执行pl.read_excel的帮助文档确认当前版本支持的参数。5.8 测试结果记录表建议把结果整理成一个统一的表格方便后续写技术总结或团队分享库组合文件格式最短耗时平均耗时能否读到 10 万行备注pandas openpyxlxlsxpandas xlrdxlsopenpyxl read_onlyxlsxopenpyxl 普通模式xlsxpython-calaminexlsxpolars calaminexlsx每列都实际跑完再填数比任何人都能给出靠谱结论。6. 内存观测方法读取 10 万行 Excel内存占用往往比耗时更值得关注。很多人的电脑不是慢在 CPU而是慢在内存不够导致频繁交换。6.1 使用 tracemalloc 统计内存分配Python 自带的tracemalloc可以统计当前进程内的内存分配情况不用安装额外包适合对比同一进程里不同读取方式的内存占用。import tracemalloc import pandas as pd tracemalloc.start() df pd.read_excel(test_100k_rows.xlsx, engineopenpyxl) current, peak tracemalloc.get_traced_memory() tracemalloc.stop() print(f当前内存: {current / 1024 / 1024:.2f} MB) print(f峰值内存: {peak / 1024 / 1024:.2f} MB)需要注意tracemalloc统计的是 Python 对象分配的内存不完全等于进程 RSS 内存。但用于横向对比不同库的相对内存消耗已经足够。6.2 使用 psutil 统计进程总内存如果想知道整个 Python 进程实际占用了多少内存可以结合psutilpip install psutilimport os import psutil def get_process_memory_mb(): process psutil.Process(os.getpid()) return process.memory_info().rss / 1024 / 1024在测试代码前后分别调用get_process_memory_mb()差值就是本次读取操作带来的大概内存增量。6.3 内存观测时的常见现象根据常见实践经验10 万行 20 列左右的 xlsx 文件在 pandas openpyxl 组合下通常能吃掉几百 MB 到 1GB 以上的内存。这是因为openpyxl 先把工作表的 XML 数据转换成单元格对象。pandas 再把这些对象转换成 NumPy / pandas 内部结构。中间对象的生命周期重叠导致内存峰值偏高。openpyxl 的read_onlyTrue模式下单元格不是全部构建成对象而是迭代式暴露行数据内存占用会明显降低。calamine 和 polars 这类 Rust 实现通常会比纯 Python 解析更节省内存但具体数值也要以实测为准。真正跑测试时推荐先观察而不是只在最后看一个总耗时。如果测试过程中出现了内存溢出或者卡死可以把问题记录到日志里用更小的文件继续对比。7. 读取结果一致性验证读取耗时只是指标之一。如果某个库为了跑得快结果解析出来是错的那效率再高也没有意义。7.1 验证 Shape最基础的检查是行数和列数for engine_name, df in results.items(): print(f{engine_name}: shape{df.shape})正常情况下所有库都应该输出(100000, 20)。如果某个库读出来的行列数和预期不一致说明它对这个 Excel 文件的解析方式有出入。7.2 校验抽样值随机抽取特定位置的单元格值确认不同库读出来的数据是一致的def verify_row(df, index12345): row df.iloc[index] print(findex{index}) print(row[[id, name, category, value1]].to_dict()) # 示例调用 # verify_row(pandas_result_df) # verify_row(calamine_result_df)需要注意不同库返回的数据类型可能不同。比如 pandas 读 Excel 时可能把某些列推断为int64或float64而 python-calamine 可能返回 Python 原生int/float。这种类型差异不算错误只要数值一致即可不需要强制完全对齐。7.3 校验缺失值实际文件里如果存在空单元格不同库的默认处理方式可能不同。有的返回None有的返回NaN。如果有空值测试需求建议单独生成一份含缺失值的文件再对比。本文生成的文件没有空值所以不需要额外处理。8. 优化读取的通用手段如果你的场景不是单纯“测一遍”而是要天天读大 Excel光知道哪个库快还不够还要学会减少无效数据、降低解析开销。8.1 指定 usecols 只读取需要的列pandas 里可以用usecols参数只保留需要的列而不是把 20 列全读出来。这样解析工作量、内存占用都会显著下降。df pd.read_excel( test_100k_rows.xlsx, engineopenpyxl, usecolsA:D )比如你只需要id、name、category、value1这 4 列Excel 文件解析范围就从 200 万格变成了 40 万格。如果文件列数很多这个优化效果非常明显。8.2 指定 dtype 避免类型推断开销pandas 读取时会自动推断每列的数据类型这一过程也有消耗。如果在读取前就能确定列类型可以显式传 dtype 参数减少推断成本df pd.read_excel( test_100k_rows.xlsx, engineopenpyxl, dtype{id: int64, category: string} )注意 openpyxl 对 dtype 的支持不完全等同于 read_csv。有时候 pandas 还是会先读成 object 再转换。如果 dtype 参数不生效可以优先考虑转成 CSV 用read_csv加载那才是 pandas 性能最强的读取路径。8.3 先转 CSV / Parquet如果 Excel 文件是你的上游数据源但后续同一份文件要读很多次强烈建议第一次用 calamine / polars 把 Excel 转成 CSV 或 Parquet。后续所有处理直接读 CSV / Parquet。CSV 是纯文本读取速度快得多Parquet 是列式存储体积小、读取更快还能保留数据类型。转换时如果文件包含时间字段要先确认时区和格式。import polars as pl pl.read_excel(test_100k_rows.xlsx, enginecalamine).write_parquet(test_100k_rows.parquet)后续所有分析都换成df pl.read_parquet(test_100k_rows.parquet)这才是处理大表格的主流工程方案。Excel 更多是数据交换和人工查看的格式不适合作为长期高频读取的数据存储格式。8.4 分块读取思路pandas 的read_excel()没有像read_csv()那么完善的分块功能。要控制内存可以自己用 openpyxl 的iter_rows()按批读取每批处理一批数据from openpyxl import load_workbook batch_size 10000 total_rows 0 wb load_workbook(test_100k_rows.xlsx, read_onlyTrue, data_onlyTrue) ws wb.active batch [] for row in ws.iter_rows(values_onlyTrue): if total_rows 0: # 第一行是表头 header row total_rows 1 continue batch.append(row) total_rows 1 if len(batch) batch_size: # 在这里处理 batch例如转为 DataFrame 后写入数据库 print(f处理了 {total_rows - 1} 行) batch [] if batch: print(f最后一批共处理 {total_rows - 1} 行) wb.close()这种方式的缺点是要自己维护表头、类型处理代码量增加优点是内存可控理论上可以处理几十万甚至上百万行数据而不撑爆内存。9. 常见问题与排查方法测试过程中大概率会遇到下面这些问题先把排错思路准备好。问题现象可能原因排查方式解决方案ImportError: Missing optional dependency openpyxl安装 pandas 时没装 openpyxlpip show openpyxlpip install openpyxlpandas 读取时报ValueError: Engine xlrd not supportedxlrd 2.x 不支持 xlsx或引擎名写错查看 pandas 版本和 xlrd 版本确认文件格式xlrd 只用于 xlsxlsx 用 openpyxl 或 calamineopenpyxl 读取时提示File is not a zip file文件并不是真正的 xlsx可能是 xls 改了后缀用文件编辑器查看文件头xlsx 本质是 zip 压缩包正确另存为 xlsx或直接用 xlrd / calamine 读 xlsread_onlyTrue时遍历多遍后结果为空openpyxl 只支持按顺序读一次重读需要重新 load_workbook查看官方文档说明每轮遍历前从新load_workbook内存占用过高导致进程被杀库的中间对象太多用 psutil 统计峰值换成 read_only / polars / calamine或转 Parquetzipfile.BadZipFile文件被 Excel 进程占用或损坏关闭 Excel重新生成文件重新保存测试 Excel 文件polars 调pl.read_excel()提示参数engine不识别polars 版本较新或较旧API 有变动运行help(pl.read_excel)按当前版本文档调整参数写法测试结果波动巨大文件在机械盘、后台有软件干扰、机器发热降频多次采样取中位数文件放固态盘关闭大型软件开空调控温xls 文件无法用 openpyxl 读取openpyxl 根本不支持 xls看错误日志用 xlrd 或 LibreOffice 转成 xlsx 再读PermissionError无法保存文件Windows 下文件被 python 进程或 Excel 占用检查进程句柄关闭相关程序或者把测试脚本路径改短挑 3 个高频问题重点说明9.1 openpyxl 读 xlsx 慢是什么原因openpyxl 的默认模式会把每个单元格都构造成Cell对象包括样式、坐标、值属性10 万行 20 列就是 200 万个对象Python 的对象创建成本非常高。解决思路是只读数据时启用read_onlyTrue。确认拿到的内容不需要样式时使用data_onlyTrue。避免遍历整张表尽量只遍历需要的列区域。如果只是取值分析优先考虑 calamine 或 polars。9.2 pandas 读 Excel 比读 CSV 慢多少通常来说相同数据量下pd.read_csv()会比pd.read_excel()快好几倍甚至更多。原因是 CSV 是纯文本扁平结构解析逻辑简单而 Excel 的 xlsx 本质是一个 zip 包里面有多份 XML 文件需要解压 XML 解析 类型转换。如果你要高频读取同一份大表建议在数据落地的第一步就转成 CSV 或 Parquet。这不仅仅是库的差异而是数据格式本身的差异。9.3 python-calamine 读出来的数据类型和 openpyxl 不一致不同解析库对 Excel 单元格类型的映射规则本来就不完全一致。例如空单元格在 openpyxl 里可能是None在 calamine 里可能也是None。日期列在不同引擎下可能返回datetime也可能返回序列号。数字列可能被识别为int、float或Decimal。遇到类型不一致时优先以“数值是否一致”为准不要把类型差异当成读取错误。如果需要统一类型在拿到数据后做一次显式转换。10. 最佳实践与使用建议把 10 万行 Excel 的读取测试经验落到工程里有几点建议值得直接记下来。10.1 先确认文件格式再决定库不要拿到文件就默认是 xlsx。很多老业务系统导出的还是 xls甚至可能只是把 xls 后缀改成 xlsx。先确认文件头再决定用哪个库# 查看文件头前 4 个字节 head -c 4 test_100k_rows.xlsx | xxdxlsx 文件头应该是PK这是 zip 压缩包的标志。如果是D0 CF 11 E0或类似字节说明其实是老版 xls 格式。10.2 第一次先跑小数据量再跑全量先用 1000 行的小文件跑通流程确认读取结果一致、耗时统计逻辑无误再换成 10 万行全量测试。否则一旦代码里有个隐蔽的 bug跑一次 10 万行文件就是在浪费时间。10.3 建立一套可复用的测试脚本把测试脚本拆成三个文件generate_data.py生成测试 Excel 文件。benchmark_read.py执行不同库的读取测试并输出耗时。check_result.py校验各库读取结果是否一致。这样以后换了新机器、换了 Python 版本、换了 Excel 文件规模都能快速再跑一次形成长期的基准测试基线。10.4 性能、内存、易用性三个指标分开看不要只追一个最快速度。实际开发里代码可维护性和生态完整度同样重要。如果你是做数据分析报告pandas 最顺手读取稍慢可接受。如果你是在做数据平台每天要同步几十个 Excel 文件polairs calamine 或先转 Parquet 更值得。如果你要保留 Excel 里原有的公式和样式openpyxl 是唯一选型。如果你的机器内存紧张优先避免 pandas openpyxl 的默认组合。10.5 涉及真实数据时先脱敏、后授权测试脚本建议使用模拟数据。如果需要用真实 Excel 文件跑性能验证比如命名不规范且包含个人信息的业务表格请先确认获取和使用的授权边界必要时做脱敏处理。不要用包含个人隐私、商业秘密或版权保护内容的文件作为公开基准测试素材也不要把这类文件传到不受控的环境里。11. 总结与后续方向这轮用 Python 常见库读取 10 万行 Excel 的基准测试核心收获可以归纳成一句话在 xlsx 数据读取场景里预期最快和最慢的实现之间通常存在显著差距性能瓶颈往往不在 Python 本身而是引擎的解析方式和中间对象的构建策略。最值得先做的一件事是把你机器上的pandas openpyxl和python-calamine或polars calamine各跑一遍把耗时填进表格看看差距到底有多大。这一步跑完你对“该选哪个库”的判断会比任何文章里的结论都准确。最容易踩的坑是老文件格式不统一同一批 Excel 里混了 xlsx、xls、xlsb不同库支持范围不一样测试过程很容易被假报错打断。建议先建一个文件格式检查脚本把所有待测文件过滤一遍统一格式再开始测。读完这篇文章之后你可以继续往这几个方向扩展把测试规模从 10 万行提升到 30 万行、50 万行观察耗时和内存的增长曲线。加入含图片、公式、合并单元格的“脏 Excel”测试看各库还能不能扛住。对比.xlsx、.xls、.xlsb、.csv、.parquet五种格式在读取速度上的差异。用 FastAPI 封装一个 Excel 上传解析接口把测试结论落地成实际服务。配合批量任务把大量 Excel 文件批量传入并输出统一的 DataFrame整理成适合入库的数据格式。建议收藏备用。下次你处理 Excel如果再有人说“Python 读 Excel 太慢了”直接把这套测试脚本甩过去让他给出自己机器上的数据。
返回列表