将 Excel 文件读取到 pandas 数据帧的更快方法
Faster way to read Excel files to pandas dataframe
我有一个 14MB Excel file with five worksheets 正在读入 Pandas 数据框,尽管下面的代码有效,但需要 9 分钟!
有没有人有加快速度的建议?
import pandas as pd
def OTT_read(xl,site_name):
df = pd.read_excel(xl.io,site_name,skiprows=2,parse_dates=0,index_col=0,
usecols=[0,1,2],header=None,
names=['date_time','%s_depth'%site_name,'%s_temp'%site_name])
return df
def make_OTT_df(FILEDIR,OTT_FILE):
xl = pd.ExcelFile(FILEDIR + OTT_FILE)
site_names = xl.sheet_names
df_list = [OTT_read(xl,site_name) for site_name in site_names]
return site_names,df_list
FILEDIR='c:/downloads/'
OTT_FILE='OTT_Data_All_stations.xlsx'
site_names_OTT,df_list_OTT = make_OTT_df(FILEDIR,OTT_FILE)
正如其他人所建议的那样,csv 读取速度更快。因此,如果您在 windows 上并拥有 Excel,您可以调用 vbscript 将 Excel 转换为 csv,然后读取 csv。我尝试了下面的脚本,它花了大约 30 秒。
# create a list with sheet numbers you want to process
sheets = map(str,range(1,6))
# convert each sheet to csv and then read it using read_csv
df={}
from subprocess import call
excel='C:\Users\rsignell\OTT_Data_All_stations.xlsx'
for sheet in sheets:
csv = 'C:\Users\rsignell\test' + sheet + '.csv'
call(['cscript.exe', 'C:\Users\rsignell\ExcelToCsv.vbs', excel, csv, sheet])
df[sheet]=pd.read_csv(csv)
这里有一小段 python 用于创建 ExcelToCsv.vbs 脚本:
#write vbscript to file
vbscript="""if WScript.Arguments.Count < 3 Then
WScript.Echo "Please specify the source and the destination files. Usage: ExcelToCsv <xls/xlsx source file> <csv destination file> <worksheet number (starts at 1)>"
Wscript.Quit
End If
csv_format = 6
Set objFSO = CreateObject("Scripting.FileSystemObject")
src_file = objFSO.GetAbsolutePathName(Wscript.Arguments.Item(0))
dest_file = objFSO.GetAbsolutePathName(WScript.Arguments.Item(1))
worksheet_number = CInt(WScript.Arguments.Item(2))
Dim oExcel
Set oExcel = CreateObject("Excel.Application")
Dim oBook
Set oBook = oExcel.Workbooks.Open(src_file)
oBook.Worksheets(worksheet_number).Activate
oBook.SaveAs dest_file, csv_format
oBook.Close False
oExcel.Quit
""";
f = open('ExcelToCsv.vbs','w')
f.write(vbscript.encode('utf-8'))
f.close()
本回答受益于Convert XLS to CSV on command line and csv & xlsx files import to pandas data frame: speed issue
如果少于 65536 行(在每个 sheet 中),您可以尝试 xls
(而不是 xlsx
。根据我的经验,xls
比 xlsx
。很难和csv
比较,因为它取决于sheet的个数。
虽然这不是一个理想的解决方案(xls
是一种二进制旧的私有格式),但我发现如果您正在使用 很多,这将很有用sheets、内部公式具有经常更新的值,或出于任何原因你真的很想保持excel多sheet功能(而不是csv分隔文件)。
我知道这是旧的,但以防万一其他人正在寻找不涉及 VB 的答案。 Pandas read_csv()
更快,但您不需要 VB 脚本来获取 csv 文件。
打开您的 Excel 文件并另存为 *.csv(逗号分隔值)格式。
在工具下,您可以 select Web 选项,在编码选项卡下,您可以将编码更改为适合您的数据的编码。我最终使用了 Windows,西欧,因为 Windows UTF 编码是 "special",但是有很多方法可以完成同样的事情。然后使用 pd.read_csv()
中的编码参数来指定您的编码。
编码选项已列出here
没有理由打开excel 如果您愿意处理一次缓慢的转换。
- 使用
pd.read_excel()
将数据读入数据帧
- 立即使用
pd.to_csv()
将其转储到 csv 中
避免 excel 和 windows 特定调用。就我而言,一次性点击是值得的。我有一个☕.
根据我的经验,Pandas read_excel()
可以很好地处理包含多个 sheet 的 Excel 文件。正如 Using Pandas to read multiple worksheets 中所建议的那样,如果您将 sheet_name
分配给 None
,它会自动将每个 sheet 放入一个 Dataframe 中,并且它会输出一个 Dataframes 字典,其键为 sheet 名字。
但需要时间的原因在于您在代码中解析文本 的位置。 14MB excel 和 5 sheets 并不算多。我有一个 20.1MB excel 的文件,其中包含 46 个 sheets,每个文件超过 6000 行和 17 列,使用 read_excel
如下所示:
t0 = time.time()
def parse(datestr):
y,m,d = datestr.split("/")
return dt.date(int(y),int(m),int(d))
data = pd.read_excel("DATA (1).xlsx", sheet_name=None, encoding="utf-8", skiprows=1, header=0, parse_dates=[1], date_parser=parse)
t1 = time.time()
print(t1 - t0)
## result: 37.54169297218323 seconds
在上面的代码中,data
是一个包含 46 个数据帧的字典。
正如其他人所建议的那样,使用 read_csv()
会有所帮助,因为读取 .csv
文件会更快。但考虑到 .xlsx
文件使用压缩这一事实,.csv
文件可能更大,因此读取速度更慢。但是,如果您想使用 python 将文件转换为逗号分隔(VBcode 由 Rich Signel), you can use: Convert xlsx to csv
提供
我使用 xlsx2csv 在内存中将 excel 文件虚拟转换为 csv,这有助于将读取时间缩短一半左右。
from xlsx2csv import Xlsx2csv
from io import StringIO
import pandas as pd
def read_excel(path: str, sheet_name: str) -> pd.DataFrame:
buffer = StringIO()
Xlsx2csv(path, outputencoding="utf-8", sheet_name=sheet_name).convert(buffer)
buffer.seek(0)
df = pd.read_csv(buffer)
return df
我鼓励您自己进行比较,看看哪种方法适合您的情况。
例如,如果您正在处理大量 XLSX 文件并且每个文件只读一次,您可能不想担心 CSV 转换。但是,如果您打算一遍又一遍地阅读 CSV,那么我强烈建议将工作簿中的每个工作表保存一次到 csv,然后使用 pd.read_csv()
.
重复阅读它们
下面是一个简单的脚本,可以让您比较 Importing XLSX Directly
、Converting XLSX to CSV in memory
和 Importing CSV
。它基于 答案。
剧透警告:如果您要多次读取文件,将 XLSX 转换为 CSV 会更快。
我对我正在处理的一些文件进行了一些测试,这是我的结果:
5,874 KB xlsx file (29,415 rows, 58 columns)
Elapsed time for [Import XLSX with Pandas]: 0:00:31.75
Elapsed time for [Convert XLSX to CSV in mem]: 0:00:22.19
Elapsed time for [Import CSV file]: 0:00:00.21
********************
202,782 KB xlsx file (990,832 rows, 58 columns)
Elapsed time for [Import XLSX with Pandas]: 0:17:04.31
Elapsed time for [Convert XLSX to CSV in mem]: 0:12:11.74
Elapsed time for [Import CSV file]: 0:00:07.11
是的!与 XLSX 的 17 分钟相比,202MB 的文件确实只用了 7 秒!!!
如果您准备好设置自己的测试,只需在 Excel 中打开 XLSX 并将其中一张工作表保存为 CSV。对于最终解决方案,您显然需要遍历工作表来处理每个工作表。
您还需要pip install rich pandas xlsx2csv
。
from rich import print
import pandas as pd
from datetime import datetime
from xlsx2csv import Xlsx2csv
from io import StringIO
def timer(name, startTime = None):
if startTime:
print(f"Timer: Elapsed time for [{name}]: {datetime.now() - startTime}")
else:
startTime = datetime.now()
print(f"Timer: Starting [{name}] at {startTime}")
return startTime
def read_excel(path: str, sheet_name: str) -> pd.DataFrame:
buffer = StringIO()
Xlsx2csv(path, outputencoding="utf-8", sheet_name=sheet_name).convert(buffer)
buffer.seek(0)
df = pd.read_csv(buffer)
return df
xlsxFileName = "MyBig.xlsx"
sheetName = "Sheet1"
csvFileName = "MyBig.csv"
startTime = timer(name="Import XLSX with Pandas")
df = pd.read_excel(xlsxFileName, sheet_name=sheetName)
timer("Import XLSX with Pandas", startTime)
startTime = timer(name="Convert XLSX to CSV first")
df = read_excel(path=xlsxFileName, sheet_name=sheetName)
timer("Convert XLSX to CSV first", startTime)
startTime = timer(name="Import CSV")
df = pd.read_csv(csvFileName)
timer("Import CSV", startTime)
我有一个 14MB Excel file with five worksheets 正在读入 Pandas 数据框,尽管下面的代码有效,但需要 9 分钟!
有没有人有加快速度的建议?
import pandas as pd
def OTT_read(xl,site_name):
df = pd.read_excel(xl.io,site_name,skiprows=2,parse_dates=0,index_col=0,
usecols=[0,1,2],header=None,
names=['date_time','%s_depth'%site_name,'%s_temp'%site_name])
return df
def make_OTT_df(FILEDIR,OTT_FILE):
xl = pd.ExcelFile(FILEDIR + OTT_FILE)
site_names = xl.sheet_names
df_list = [OTT_read(xl,site_name) for site_name in site_names]
return site_names,df_list
FILEDIR='c:/downloads/'
OTT_FILE='OTT_Data_All_stations.xlsx'
site_names_OTT,df_list_OTT = make_OTT_df(FILEDIR,OTT_FILE)
正如其他人所建议的那样,csv 读取速度更快。因此,如果您在 windows 上并拥有 Excel,您可以调用 vbscript 将 Excel 转换为 csv,然后读取 csv。我尝试了下面的脚本,它花了大约 30 秒。
# create a list with sheet numbers you want to process
sheets = map(str,range(1,6))
# convert each sheet to csv and then read it using read_csv
df={}
from subprocess import call
excel='C:\Users\rsignell\OTT_Data_All_stations.xlsx'
for sheet in sheets:
csv = 'C:\Users\rsignell\test' + sheet + '.csv'
call(['cscript.exe', 'C:\Users\rsignell\ExcelToCsv.vbs', excel, csv, sheet])
df[sheet]=pd.read_csv(csv)
这里有一小段 python 用于创建 ExcelToCsv.vbs 脚本:
#write vbscript to file
vbscript="""if WScript.Arguments.Count < 3 Then
WScript.Echo "Please specify the source and the destination files. Usage: ExcelToCsv <xls/xlsx source file> <csv destination file> <worksheet number (starts at 1)>"
Wscript.Quit
End If
csv_format = 6
Set objFSO = CreateObject("Scripting.FileSystemObject")
src_file = objFSO.GetAbsolutePathName(Wscript.Arguments.Item(0))
dest_file = objFSO.GetAbsolutePathName(WScript.Arguments.Item(1))
worksheet_number = CInt(WScript.Arguments.Item(2))
Dim oExcel
Set oExcel = CreateObject("Excel.Application")
Dim oBook
Set oBook = oExcel.Workbooks.Open(src_file)
oBook.Worksheets(worksheet_number).Activate
oBook.SaveAs dest_file, csv_format
oBook.Close False
oExcel.Quit
""";
f = open('ExcelToCsv.vbs','w')
f.write(vbscript.encode('utf-8'))
f.close()
本回答受益于Convert XLS to CSV on command line and csv & xlsx files import to pandas data frame: speed issue
如果少于 65536 行(在每个 sheet 中),您可以尝试 xls
(而不是 xlsx
。根据我的经验,xls
比 xlsx
。很难和csv
比较,因为它取决于sheet的个数。
虽然这不是一个理想的解决方案(xls
是一种二进制旧的私有格式),但我发现如果您正在使用 很多,这将很有用sheets、内部公式具有经常更新的值,或出于任何原因你真的很想保持excel多sheet功能(而不是csv分隔文件)。
我知道这是旧的,但以防万一其他人正在寻找不涉及 VB 的答案。 Pandas read_csv()
更快,但您不需要 VB 脚本来获取 csv 文件。
打开您的 Excel 文件并另存为 *.csv(逗号分隔值)格式。
在工具下,您可以 select Web 选项,在编码选项卡下,您可以将编码更改为适合您的数据的编码。我最终使用了 Windows,西欧,因为 Windows UTF 编码是 "special",但是有很多方法可以完成同样的事情。然后使用 pd.read_csv()
中的编码参数来指定您的编码。
编码选项已列出here
没有理由打开excel 如果您愿意处理一次缓慢的转换。
- 使用
pd.read_excel()
将数据读入数据帧
- 立即使用
pd.to_csv()
将其转储到 csv 中
避免 excel 和 windows 特定调用。就我而言,一次性点击是值得的。我有一个☕.
根据我的经验,Pandas read_excel()
可以很好地处理包含多个 sheet 的 Excel 文件。正如 Using Pandas to read multiple worksheets 中所建议的那样,如果您将 sheet_name
分配给 None
,它会自动将每个 sheet 放入一个 Dataframe 中,并且它会输出一个 Dataframes 字典,其键为 sheet 名字。
但需要时间的原因在于您在代码中解析文本 的位置。 14MB excel 和 5 sheets 并不算多。我有一个 20.1MB excel 的文件,其中包含 46 个 sheets,每个文件超过 6000 行和 17 列,使用 read_excel
如下所示:
t0 = time.time()
def parse(datestr):
y,m,d = datestr.split("/")
return dt.date(int(y),int(m),int(d))
data = pd.read_excel("DATA (1).xlsx", sheet_name=None, encoding="utf-8", skiprows=1, header=0, parse_dates=[1], date_parser=parse)
t1 = time.time()
print(t1 - t0)
## result: 37.54169297218323 seconds
在上面的代码中,data
是一个包含 46 个数据帧的字典。
正如其他人所建议的那样,使用 read_csv()
会有所帮助,因为读取 .csv
文件会更快。但考虑到 .xlsx
文件使用压缩这一事实,.csv
文件可能更大,因此读取速度更慢。但是,如果您想使用 python 将文件转换为逗号分隔(VBcode 由 Rich Signel), you can use: Convert xlsx to csv
我使用 xlsx2csv 在内存中将 excel 文件虚拟转换为 csv,这有助于将读取时间缩短一半左右。
from xlsx2csv import Xlsx2csv
from io import StringIO
import pandas as pd
def read_excel(path: str, sheet_name: str) -> pd.DataFrame:
buffer = StringIO()
Xlsx2csv(path, outputencoding="utf-8", sheet_name=sheet_name).convert(buffer)
buffer.seek(0)
df = pd.read_csv(buffer)
return df
我鼓励您自己进行比较,看看哪种方法适合您的情况。
例如,如果您正在处理大量 XLSX 文件并且每个文件只读一次,您可能不想担心 CSV 转换。但是,如果您打算一遍又一遍地阅读 CSV,那么我强烈建议将工作簿中的每个工作表保存一次到 csv,然后使用 pd.read_csv()
.
下面是一个简单的脚本,可以让您比较 Importing XLSX Directly
、Converting XLSX to CSV in memory
和 Importing CSV
。它基于
剧透警告:如果您要多次读取文件,将 XLSX 转换为 CSV 会更快。
我对我正在处理的一些文件进行了一些测试,这是我的结果:
5,874 KB xlsx file (29,415 rows, 58 columns)
Elapsed time for [Import XLSX with Pandas]: 0:00:31.75
Elapsed time for [Convert XLSX to CSV in mem]: 0:00:22.19
Elapsed time for [Import CSV file]: 0:00:00.21
********************
202,782 KB xlsx file (990,832 rows, 58 columns)
Elapsed time for [Import XLSX with Pandas]: 0:17:04.31
Elapsed time for [Convert XLSX to CSV in mem]: 0:12:11.74
Elapsed time for [Import CSV file]: 0:00:07.11
是的!与 XLSX 的 17 分钟相比,202MB 的文件确实只用了 7 秒!!!
如果您准备好设置自己的测试,只需在 Excel 中打开 XLSX 并将其中一张工作表保存为 CSV。对于最终解决方案,您显然需要遍历工作表来处理每个工作表。
您还需要pip install rich pandas xlsx2csv
。
from rich import print
import pandas as pd
from datetime import datetime
from xlsx2csv import Xlsx2csv
from io import StringIO
def timer(name, startTime = None):
if startTime:
print(f"Timer: Elapsed time for [{name}]: {datetime.now() - startTime}")
else:
startTime = datetime.now()
print(f"Timer: Starting [{name}] at {startTime}")
return startTime
def read_excel(path: str, sheet_name: str) -> pd.DataFrame:
buffer = StringIO()
Xlsx2csv(path, outputencoding="utf-8", sheet_name=sheet_name).convert(buffer)
buffer.seek(0)
df = pd.read_csv(buffer)
return df
xlsxFileName = "MyBig.xlsx"
sheetName = "Sheet1"
csvFileName = "MyBig.csv"
startTime = timer(name="Import XLSX with Pandas")
df = pd.read_excel(xlsxFileName, sheet_name=sheetName)
timer("Import XLSX with Pandas", startTime)
startTime = timer(name="Convert XLSX to CSV first")
df = read_excel(path=xlsxFileName, sheet_name=sheetName)
timer("Convert XLSX to CSV first", startTime)
startTime = timer(name="Import CSV")
df = pd.read_csv(csvFileName)
timer("Import CSV", startTime)