ExcelFile与read_excel是pandas中处理excel文件的两个方法。本文将从实例进行说明,来介绍这两种方法的区别。事实上,尽管预料到pandas同时支持这两种方法,但整体上我还不知道pandas对这两个方法的定位是什么。而通过整理这两个方法,可以在工作之余探究pandas对这两个方法的定位。本文主要参考了ExcelFile与read_excel的文档进行整理。
首先给出两个方法的简单使用
#ExcelFile方法的使用
path1 ="test.xlsx"
xlFile = pd.ExcelFile(path1)
df1 = xlFile.parse("Sheet1") #引号内是path对应excel文件的sheet_name
#read_excel方法的使用
path2 ="test.xlsx"
df2 = pd.io.excel.read_excel(path2, sheetname=0)
整体而言,从技术上讲,Excelfile是一个类,而read_excel是一个函数。无论哪种情况,两个方法的实际解析都是由ExcelFile中定义的_parse_excel方法处理的。其中,在早期版本的pandas中,read_excel完全由单个语句(注释除外)组成(如下所示),ExcelFile.parse并没有比调用ExcelFile._parse_excel多得多。
return ExcelFile(
path_or_buf,
kind=kind
).parse(
sheetname=sheetname,
kind=kind,
**kwds
)
在最新版本的pandas中,read_excel确保它具有一个Excelfile对象(如果没有则创建一个对象),然后直接调用_parse_excel方法:
if not isinstance(io, ExcelFile):
io = ExcelFile(io, engine=engine)
return io._parse_excel(...)
以及经过更新(统一)的参数处理,ExcelFile.parse实际上只是单个语句:
return self._parse_excel(...)
这就是为什么ExcelFile.parse的文档现在说
Equivalent to read_excel(ExcelFile, ...) See the read_excel docstring for more info on accepted parameters
的原因。
对于另一个声称ExcelFile.parse在循环中更快的答案,这实际上取决于是否每次都是从头开始创建Excelfile对象。我们当然可以在循环外创建一次Excelfile,然后将其传递到循环内的read_excel:
xl = pd.ExcelFile(path)
for name in xl.sheet_names:
df = pd.read_excel(xl, name)
这等同于
xl = pd.ExcelFile(path)
for name in xl.sheet_names:
df = xl.parse(name)
如果循环涉及不同的路径(换句话说,当前循环正在阅读许多不同的工作簿,而不仅仅是单个工作簿中的多个工作表),那么我们就不必为它创建一个全新的Excelfile实例,然后再次ExcelFile.parse和read_excel将是等效的(并且同样慢)。
这一点很符合实际,在实践中常常可以发现read_excel是比较慢的,之后的实践中,可以先通过ExcelFile传递一个对象到内存中,这样再进行数据读取会更快。