Как ускорить импорт больших файлов xlsx? - PullRequest
2 голосов
/ 21 апреля 2019

Я хочу обработать большой файл Excel (xlsx) объемом 200 МБ с 15 листами и 1 миллионом строк по 5 столбцов в каждом) и создать кадр данных pandas из данных. Импорт файла Excel очень медленный (до 10 минут). К сожалению, формат файла импорта Excel является обязательным (я знаю, что CSV быстрее ...).

Как я могу ускорить процесс импорта большого файла Excel в кадр данных pandas? Было бы здорово сократить время до 1-2 минут, если это возможно, что было бы гораздо более терпимым.

Что я пробовал до сих пор:

Вариант 1 - I / O Pandas 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 - Dask

%%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

Простое создание отдельных файлов CSV из книги Excel заняло около 10 минут, прежде чем даже импортировать файлы CSV в кадр данных pandas с помощью read_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)

Я использую Python 3.7.3 (64 бита) на одной машине (Windows 10), 16 ГБ ОЗУ, 8 ядер (i7-8650U CPU @ 1,90 ГГц). Я запускаю код в своей среде IDE (код Visual Studio).

1 Ответ

1 голос
/ 21 апреля 2019

Сжатие не является узким местом, проблема заключается в разборе XML и создании новых структур данных в Python. Судя по скоростям, которые вы цитируете, я предполагаю, что это очень большие файлы: подробности смотрите в примечании по производительности в документации. И xlrd, и openpyxl работают близко к пределам нижележащих библиотек Python и C.

Начиная с openpyxl 2.6 у вас есть опция values_only при чтении ячеек, которая немного ускорит процесс. Вы также можете использовать несколько процессов в режиме только для чтения, чтобы читать таблицы параллельно, что должно ускорить процесс, если у вас несколько процессоров.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...