将Excel文件读取到pandas dataframe的更快方法

yqhsw0fo  于 2023-06-20  发布在  其他
关注(0)|答案(8)|浏览(239)

我有一个14MB Excel file with five worksheets,我正在阅读一个Pandas Dataframe ,虽然下面的代码工作,它需要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)
wbrvyc0a

wbrvyc0a1#

正如其他人所建议的,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)

下面是创建ExcelToCsv.vbs脚本的一小段python代码:

#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 linecsv & xlsx files import to pandas data frame: speed issue

vu8f3i0k

vu8f3i0k2#

我使用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
agyaoht7

agyaoht73#

如果你有少于65536行(在每个工作表中),你可以尝试xls(而不是xlsx)。根据我的经验,xlsxlsx快。很难与csv进行比较,因为它取决于张数。
虽然这不是一个理想的解决方案(xls是一个二进制旧的privative格式),我发现这是有用的,如果你正在使用***许多工作表***,内部公式***与值经常更新***,或无论出于什么原因,你真的想*保持excel多表功能(而不是csv分隔文件)。

7gs2gvoe

7gs2gvoe4#

根据我的经验,Pandas read_excel()可以很好地处理包含多个工作表的Excel文件。正如Using Pandas to read multiple worksheets中所建议的,如果您将sheet_name分配给None,它将自动将每个工作表放入Dataframe中,并将输出一个Dataframe字典,其中包含工作表名称的键。
但它需要时间的原因是你在代码中解析文本的地方。14MB的excel和5张表并没有那么多。我有一个20.1MB的Excel文件,其中有46张表格,每张表格有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个 Dataframe 的字典。
正如其他人建议的那样,使用read_csv()可以帮助,因为阅读.csv文件更快。但是考虑到.xlsx文件使用压缩的事实,.csv文件可能更大,因此读取速度更慢。但是如果你想使用python将文件转换为逗号分隔(Rich Signel提供VBcode),你可以用途:Convert xlsx to csv

nuypyhwy

nuypyhwy5#

我知道这是旧的,但如果其他人正在寻找一个不涉及VB的答案。Pandas read_csv() * 更快,但你不需要VB脚本来获取csv文件。
打开Excel文件并保存为 *.csv(逗号分隔值)格式。
在工具下,您可以选择Web选项,在编码选项卡下,您可以将编码更改为适合您的数据的任何编码。我最终使用了西欧的Windows,因为Windows UTF编码是“特殊的”,但有很多方法可以完成同样的事情。然后使用pd.read_csv()中的encoding参数指定编码。
此处列出了编码选项

laawzig2

laawzig26#

我鼓励你自己做比较,看看哪种方法适合你的情况。
例如,如果您正在处理大量XLSX文件,并且只打算读取每个文件一次,则可能不想担心CSV转换。但是,如果您要反复阅读CSV,那么我强烈建议将工作簿中的每个工作表保存到CSV中一次,然后使用pd.read_csv()反复阅读它们。
下面是一个简单的脚本,可以让您比较Importing XLSX DirectlyConverting XLSX to CSV in memoryImporting CSV。它基于Jing Xue's答案。
剧透警告:如果您要多次读取文件,将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

是的!202 MB的文件确实只花了7秒钟,而XLSX只花了17分钟!!!
如果您准备设置自己的测试,只需在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)
a1o7rhls

a1o7rhls7#

最近有一个类似的问题,并通过使用库xlwings解决了它:

import xlwings as xw
import pandas as pd

def xw_excel_to_df(file_path, sheet_name=None, sheet_range=None):
    app = xw.App()
    book = xw.Book(file_path, read_only=True)

    if sheet_name is None:
        sheet_name = book.sheets[0].name

    if sheet_range is None:
        data = book.sheets[sheet_name]["A1"].expand().value
    else:
        data = book.sheets[sheet_name][sheet_range].value

    df = pd.DataFrame(data=data[1:], columns=data[0])

    book.close()
    app.quit()

    return df

基本上,它在本地打开一个Excel示例,读取数据,将其加载到数据框中,然后关闭Excel。
您必须在PC中安装Excel,然后您可能必须解决一些依赖关系才能在远程使用此资源。
使用它的一些本地分析使用jupyter笔记本,顺便说一句,工作完美的我!:)

ct3nt3jp

ct3nt3jp8#

没有理由打开excel * 如果 * 你愿意处理一次缓慢的转换。
1.使用pd.read_excel()将数据读入 Dataframe
1.立即使用pd.to_csv()将其转储到csv中
避免excel和windows特定的调用。在我的情况下,一次性的打击是值得的麻烦。我得到了一个。

相关问题