我想处理一个200MB的大型Excel(xlsx)文件,其中包含15张工作表和100万行(各有5列),并根据数据创建熊猫数据框。 Excel文件的导入非常慢(最多10分钟)。不幸的是,Excel导入文件格式是强制性的(我知道csv更快...)。
如何加快将大Excel文件导入熊猫数据框的过程?如果可能的话,将时间缩短到1-2分钟左右将是很棒的,这将是可以忍受的。
到目前为止,我已经尝试过:
选项1-熊猫I / O read_excel
%%timeit -r 1
import pandas as pd
import datetime
xlsx_file = pd.ExcelFile("Data.xlsx")
list_sheets = []
for sheet in xlsx_file.sheet_names:
list_sheets.append(xlsx_file.parse(sheet, header = 0, dtype={
"Sales": float,
"Client": str,
"Location": str,
"Country": str,
"Date": datetime.datetime
}).fillna(0))
output_dataframe = pd.concat(list_sheets)
10min 44s ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)
选项2-快达
%%timeit -r 1
import pandas as pd
import dask
import dask.dataframe as dd
from dask.delayed import delayed
excel_file = "Data.xlsx"
parts = dask.delayed(pd.read_excel)(excel_file, sheet_name=0)
output_dataframe = dd.from_delayed(parts)
10min 12s ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)
选项3-openpyxl和csv
从Excel工作簿创建单独的csv文件大约需要10分钟,然后甚至可以通过read_csv
将csv文件导入到熊猫数据框
%%timeit -r 1
import openpyxl
import csv
from openpyxl import load_workbook
wb = load_workbook(filename = "Data.xlsx", read_only=True)
list_ws = wb.sheetnames
nws = len(wb.sheetnames) #number of worksheets in workbook
# create seperate csv files from each worksheet (15 in total)
for i in range(0, nws):
ws = wb[list_ws[i]]
with open("output/%s.csv" %(list_ws[i].replace(" ","")), "w", newline="") as f:
c = csv.writer(f)
for r in ws.rows:
c.writerow([cell.value for cell in r])
9min 31s ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)
我在一台计算机(Windows 10),16GB RAM,8核(i7-8650U CPU @ 1.90GHz)上使用Python 3.7.3(64bit)。我在IDE中运行代码(Visual Studio代码)。
答案 0 :(得分:1)
压缩不是瓶颈,问题在于解析XML并在Python中创建新的数据结构。从您引用的速度来看,我假设它们是非常大的文件:有关更多详细信息,请参见文档中有关性能的说明。 xlrd和openpyxl都在接近底层Python和C库的极限运行。
从openpyxl 2.6开始,您在读取单元格时确实具有values_only
选项,这会加快速度。您还可以将多个进程与只读模式一起使用,以并行方式读取工作表,如果您有多个处理器,则可以加快工作速度。
答案 1 :(得分:0)
您可以使用 fread
包中的 datatable
,这是(可能仍然是)自我记得上次以来 R 中最快的包。查看包裹的 official page 了解更多详情。
from datatable import fread
import pandas as pd
excel_path = "my_excel_file.xlsx"
df = fread(excel_path+"/sheet_name").to_pandas()