Python pandas与openpyxl读取指定Sheet的性能对比与选择

阿澈
阿澈
发布时间:2026-10-28 | 10人浏览过
原创

深入对比Python中使用pandas与openpyxl读取Excel指定工作表(Sheet)的性能表现、内存占用机制及适用场景,提供完整的代码范例与选型决策指南。

在 Python 自动化办公与数据处理中,读取 Excel 文件的指定工作表(Sheet)是极为高频的操作。核心结论十分明确:若任务后续依赖数据清洗、统计分析或建模,pandas 凭借直接生成高效 DataFrame 成为首选;若文件体积较大(数十兆以上)、运行环境内存受限,或者仅需提取几条特定单元格数据,openpyxl 的只读流式模式(read_only=True) 在内存控制与启动耗时上具有压倒性优势。

一、核心差异与选型速查

很多开发者直觉认为 pandas 读取速度较慢,而 openpyxl 更原生。事实上,pandas 默认正是调用 openpyxl 作为底层的解析引擎,但在数据加载路径和内存表示方式上存在本质分歧。下表对两者读取指定工作表的核心维度进行了对比:

对比维度 pandas (read_excel) openpyxl (普通模式) openpyxl (只读模式 read_only=True)
底层定位 科学计算与数据分析库 完整 Office Open XML 读写引擎 轻量流式只读解析器
读取指定Sheet语法 sheet_name='Sheet1' wb['Sheet1'] wb['Sheet1']
内存占用峰值 中等偏高(需构建连续内存块与索引) 极高(每个单元格封装为完整 Python 对象) 极低(恒定在数十兆内,流式生成器)
解析执行速度 中等(底层解析 + C 级向量转换) 慢(全量构建 DOM 语法树) 快(仅解析目标 XML 标签流)
结果数据形态 pandas.DataFrame openpyxl.worksheet.worksheet.Worksheet openpyxl.worksheet._read_only.ReadOnlyWorksheet
最适用业务场景 后续需要数据清洗、分组统计与机器学习 需读取格式、合并单元格信息或后续原样写回 大体量文件只读扫描、低内存服务器批量作业
Python pandas与openpyxl读取指定Sheet的性能对比与选择
图 1:pandas 与 openpyxl 两种底层解析方式与内存映射模型

二、指定 Sheet 读取方式与完整代码示例

在实际编写脚本时,针对指定 Sheet 的定位方式与读取代码有明确的范式。以下提供经过验证的生产级标准代码。

1. pandas 读取指定 Sheet

pandas 通过 pandas.read_excel 的 sheet_name 参数指定目标工作表。支持传入字符串(工作表名称)或整数索引(从 0 开始)。

import pandas as pd

# 执行环境要求:pip install pandas openpyxl
file_path = "sales_report_2026.xlsx"
target_sheet = "March_Summary"

# 读取指定名称的Sheet,并明确指定解析引擎
df = pd.read_excel(
    io=file_path,
    sheet_name=target_sheet,
    engine="openpyxl"
)

# 查看读取结果形态
print(f"成功读取工作表: {target_sheet}")
print(f"数据维度: {df.shape[0]} 行, {df.shape[1]} 列")
print("示例输出前两行:")
print(df.head(2))

执行输出示例:

成功读取工作表: March_Summary
数据维度: 50000 行, 15 列
示例输出前两行:
   Order_ID  Region     Sales  Profit
0  ORD-1001   North  12500.50  3200.0
1  ORD-1002    East   8400.00  1850.5
注意事项: 若未传递 sheet_name,默认只读取第 0 个 Sheet;若传递 sheet_name=None,pandas 会完整遍历并读取工作簿内的所有 Sheet 并返回一个字典,这将导致巨大的性能损耗和内存开销。当只需单个 Sheet 时,必须传入具体名称或索引。

2. openpyxl 普通模式读取指定 Sheet

openpyxl 通过工作簿字典下标 wb[sheet_name] 访问特定工作表,普通模式下会预先加载结构。

from openpyxl import load_workbook

file_path = "sales_report_2026.xlsx"
target_sheet = "March_Summary"

# 普通模式加载,data_only=True 表示读取公式计算后的数值而非公式文本
wb = load_workbook(filename=file_path, data_only=True)
ws = wb[target_sheet]

# 读取指定单元格或遍历行
cell_val = ws["B2"].value
print(f"工作表 {target_sheet} B2 单元格数值为: {cell_val}")

# 关闭工作簿释放句柄
wb.close()

3. openpyxl 只读模式(read_only=True)高性能流式读取

当数据量超过数万行时,开启 read_only=True 是 openpyxl 的关键优化选项。该模式不会构建庞大的 DOM 单元格对象树,而是以生成器形式按需扫描。

from openpyxl import load_workbook

file_path = "sales_report_2026.xlsx"
target_sheet = "March_Summary"

# 开启只读流式模式
wb = load_workbook(filename=file_path, read_only=True, data_only=True)

if target_sheet in wb.sheetnames:
    ws = wb[target_sheet]
    row_count = 0
    total_sales = 0.0

    # 使用 values_only=True 直接返回纯数值元组,极大提高遍历效率
    for row in ws.iter_rows(min_row=2, values_only=True):
        row_count += 1
        sales = row[2]  # 假设第3列为Sales
        if sales is not None:
            total_sales += float(sales)

    print(f"工作表 {target_sheet} 统计完成:")
    print(f"有效数据行数: {row_count}")
    print(f"销售额累计值: {total_sales:.2f}")

# 务必在流式读取完毕后关闭句柄
wb.close()
Python pandas与openpyxl读取指定Sheet的性能对比与选择
图 2:Excel 读取指定工作表完整步骤与执行开销阶段

三、性能实测维度与指标对比

为了给出具有说服力的量化选型依据,在统一测试环境(Python 3.11,配置 16GB 内存)下,针对三种不同数据量级的工作簿进行了基准压测。对比维度包括加载耗时(秒)与内存峰值(MB)。

  • 小型数据集:单工作簿包含 1 个 Sheet,10,000 行 × 15 列(约 2.5 MB)。
  • 中型数据集:单工作簿包含 3 个 Sheet,读取其中 1 个 100,000 行 × 15 列的 Sheet(约 25 MB)。
  • 大型多Sheet数据集:工作簿包含 5 个 Sheet,每个 Sheet 均有 50,000 行,总文件大小约 65 MB,专门测试读取第 4 个 Sheet 的效率。
Python pandas与openpyxl读取指定Sheet的性能对比与选择
图 3:不同数据规模下两库耗时与内存占用实测对比

四、常见开发陷阱与优化建议

在实际生产环境中处理 Excel 时,仅了解基本语法容易遇到性能瓶颈或内存溢出。以下是 4 个需要重点规避的常见陷阱:

1. 误用 openpyxl 普通模式处理超大表格引发 OOM

从实测数据可见,当表格达到 10 万行时,openpyxl 普通模式会消耗超过 1.3 GB 内存。这是因为 openpyxl 为每个单元格创建了包含坐标、格式、边框、字体在内的丰富对象树。在内存有限的容器环境或云函数中,极易触发 OOM(Out of Memory)进程被杀。

避坑准则: 只要不需要修改原文件并写回样式,所有涉及大量数据的 openpyxl 读取操作,必须显式添加 read_only=True。

2. pandas 遍历多个 Sheet 时的误用

如果一个工作簿中有 10 个 Sheet,业务需要分别读取其中 3 个:

  • 低效写法:连续调用三次 pd.read_excel(file_path, sheet_name=name)。这会导致整个 zip 包被解压并加载三次。
  • 高效优化写法:使用 pd.ExcelFile 复用工作簿句柄:
import pandas as pd

file_path = "multi_sheet_data.xlsx"

# 推荐:使用 ExcelFile 对象只打开一次工作簿
with pd.ExcelFile(file_path, engine="openpyxl") as reader:
    # 打印包含的所有Sheet名称
    print("可用Sheets:", reader.sheet_names)
    
    # 按需分别读取指定工作表,无需重复解压归档
    df_sales = pd.read_excel(reader, sheet_name="Sales_Data")
    df_targets = pd.read_excel(reader, sheet_name="Targets")

3. openpyxl 只读模式下的尺寸获取与重读限制

在 read_only=True 模式下,工作表不会预先统计总行数和总列数。此时直接调用 ws.max_row 往往返回 None,或者返回文件元数据中记录的不准确预估值。

此外,ws.iter_rows() 返回的是单向生成器,不能像普通列表一样进行反向切片或二次迭代。如需统计行数,应在流式扫描时累加计数器。

4. 替代高性能引擎加速 pandas(calamine 引擎)

如果业务强制要求输出 DataFrame,但 openpyxl 引擎速度无法满足实时接口需求,推荐在 Python 环境中安装基于 Rust 编写的 python-calamine 引擎:

# 依赖安装:pip install python-calamine
import pandas as pd

# 使用 calamine 替代 openpyxl 引擎,读取指定 Sheet 的速度可提升 3~5 倍
df = pd.read_excel("large_file.xlsx", sheet_name="Sheet1", engine="calamine")

五、场景选型决策指南

在实际技术方案选型中,请结合数据后续去向、硬件配置与业务要求,参考下方决策指南进行选择。

Python pandas与openpyxl读取指定Sheet的性能对比与选择
图 4:读取 Excel 指定工作表综合决策树

六、总结与落地建议

在处理“读取指定 Sheet”这一具体需求时,技术的选择实质上是数据结构与内存利用方式的权衡:

  1. 开箱即用首选 pandas: 只要数据体量适中(单表 10 万行以内),且后续需要按列做数据清洗或聚合运算,使用 pd.read_excel(file, sheet_name="TargetSheet") 能够最大程度节省代码量并降低开发维护成本。
  2. 海量数据与低内存环境首选 openpyxl(read_only=True): 当面临多 Sheet 超大报表扫描、抽取固定单元格数据入库或服务器内存告警时,坚决采用 openpyxl.load_workbook(file, read_only=True),它能保证程序以恒定的几十兆内存平稳完成作业。
  3. 避免重复解压与非必要全量加载: 多次读取同文件不同工作表时使用 pd.ExcelFile;严禁在无修改格式需求的大文件上使用 openpyxl 的普通模式,防止无谓的内存浪费与 OOM 故障。
相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表