alitrack

Python读取Excel太慢?可能你方法不正确

在数据处理和分析的领域中,从 Excel 表格中提取数据是一个常见的任务。但当 Excel 很大的时候,读取变得非常慢,那有没有啥解决办法呢?

今天就介绍两个新方法,并和你熟悉的方法做个对比。

测试数据

Online Retail.xlsx[1]
这是一个涉及英国注册的非实体在线零售公司在 2010 年 12 月 1 日至 2011 年 12 月 9 日期间所有交易的跨国数据集。该公司主要销售独特的全场合礼品,许多公司客户都是批发商。
该数据集总共有 50多万行(541909) 条数据。

变量表

变量名称角色类型人口统计学描述单位缺失值
InvoiceNo(发票号码)ID分类
每笔交易分配的唯一的 6 位整数编号。如果此代码以字母 'c' 开头,表示取消
无
StockCode(存货代码)ID分类
每个不同产品分配的唯一的 5 位整数编号
无
Description(描述)特征分类
产品名称
无
Quantity(数量)特征整数
每笔交易中每个产品(商品)的数量
无
InvoiceDate(发票日期)特征日期
生成每笔交易的日期和时间
无
UnitPrice(单价)特征连续
单位产品价格英镑无
CustomerID(客户 ID)特征分类
每个客户分配的唯一的 5 位整数编号
无
Country(国家)特征分类
每个客户所在国家的名称
无

选择这个数据集,是因为它是真实数据,包含了字符串、日期、数字类型。

速度比拼

import pandas as pd
file_path="/Users/m2max/data/Online Retail.xlsx"

大家都熟悉的传统方案:openpyxl Engine

%%time
df = pd.read_excel(file_path, engine="calamine")

Image

openpyxl engine

方案二,DuckDB

%%time
import duckdb

duckdb.install_extension('spatial')
duckdb.load_extension('spatial')

df = duckdb.execute(
        "SELECT * FROM st_read(?, open_options=['HEADERS=FORCE', 'FIELD_TYPES=AUTO'])",[file_path]).df()
df.head()

Image

DuckDB

方案三, calamine Engine

calamine 是一个纯 Rust 库,用于读取和反序列化任何电子表格文件:

  • Excel 类型的文件(xls、xlsx、xlsm、xlsb、xla、xlam)
  • OpenDocument 电子表格文件(ods)

Pandas 2.2 开始引入了 calamine
要使用该引擎,需要安装包

pip install python-calamine
%%time
df = pd.read_excel(file_path, engine="calamine")
df.head()

Image

calamine engine

如果你的 pandas 在 2.0 以上,但小于 2.2,

%%time
from pandas import read_excel
from python_calamine.pandas import pandas_monkeypatch
pandas_monkeypatch()
df = pd.read_excel(file_path, engine="calamine")
df.head()

如果 pandas 小于 2 咋办?

%%time
from python_calamine import CalamineWorkbook

workbook = CalamineWorkbook.from_path(file_path)
workbook.sheet_names
sheet = workbook.get_sheet_by_index(0)
data = sheet.to_python()
df = pd.DataFrame(data[1:], columns=data[0])
df.head()

Image

calamine

结论

从上面的对比可以看出,DuckDB 最快, calamine 次之,openpyxl 最慢。

方法用时(s)
DuckDB2.6
calamine engine4.1
openpyxl engine19.3
calamine2.52
更多Excel处理的文章请搜索,
参考资料
[1]

Online Retail.xlsx: https://archive.ics.uci.edu/dataset/352/online+retail