Более быстрый способ чтения файлов 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, если вы готовы иметь дело с медленным преобразованием один раз.
- Считайте данные в кадр данных с помощью
pd.read_excel()
- Скопируйте его в 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