Более быстрый способ чтения файлов Excel в pandas dataframe

У меня есть 14-мегабайтный Excel файл с пятью листами, который я читаю в 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)

Ответ 1

Как показали другие, чтение csv происходит быстрее. Поэтому, если вы находитесь в Windows и имеете Excel, вы можете вызвать vbscript для преобразования Excel в csv, а затем прочитать csv. Я попробовал script ниже, и потребовалось около 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 script:

#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()

Этот ответ выиграл Преобразовать XLS в CSV в командной строке и импортировать файлы csv и xlsx в фреймворк pandas: скорость выпуска

Ответ 2

Если у вас меньше 65536 строк (на каждом листе), вы можете попробовать xls (вместо xlsx. По моему опыту xls быстрее, чем xlsx. Трудно сравнить с csv потому что это зависит от количества листов.

Хотя это не идеальное решение (xls - это двоичный старый приватный формат), я нашел, что полезно, если у вас слишком много листов, внутренние формулы со значениями, которые часто обновляются, или по какой-либо причине вам действительно хотелось бы сохранить функциональность excel multisheet.

Ответ 3

Я знаю, что это старо, но в случае, если кто-то еще ищет ответ, который не касается VB. Pandas read_csv() работает быстрее, но вам не нужен скрипт VB для получения файла csv.

Откройте файл Excel и сохраните в формате *.csv (значение, разделенное запятыми).

Под инструментами вы можете выбрать Веб-параметры, а на вкладке Кодировка вы можете изменить кодировку на ту, которая работает для ваших данных. Я закончил тем, что использовал Windows, западноевропейский, потому что кодировка Windows UTF "особенная", но есть много способов сделать то же самое. Затем используйте аргумент кодировки в pd.read_csv() чтобы указать кодировку.

Варианты кодирования перечислены здесь

Ответ 4

Нет никаких причин открывать Excel, если вы готовы иметь дело с медленным преобразованием один раз.

  1. Считайте данные в кадр данных с помощью pd.read_excel()
  2. Скопируйте его в CSV файл сразу с pd.to_csv()

Избегайте вызовов Excel и Windows. В моем случае одноразовый удар стоил хлопот. Я получил ☕.

Ответ 5

По моему опыту, Pandas read_excel() прекрасно работает с файлами Excel с несколькими листами. Как указано в Использование Pandas для чтения нескольких рабочих листов, если вы назначите sheet_name для None, он автоматически поместит каждый лист в Dataframe и выведет словарь Dataframes с ключами имен листов.

Но причина, по которой это занимает время, заключается в том, что вы анализируете тексты в своем коде. 14MB Excel с 5 листами не так уж много. У меня есть файл Excel объемом 20,1 МБ с 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 фреймов данных.

Как предлагали другие, использование read_csv() может помочь, потому что чтение файла .csv происходит быстрее. Но учтите, что из-за того, что файлы .xlsx используют сжатие, файлы .csv могут быть больше и, следовательно, медленнее читать. Но если вы хотите преобразовать свой файл в запятую с помощью Python (VBcode предлагает Rich Signel), вы можете использовать: Преобразовать xlsx в csv