Pull to refresh

Comments 6

нет способа приспособиться к тому, что в одном столбце оказываются разные типы данных.

Всё есть в Pandas:

pd.read_excel(..., dtype='str')

Конечно, можно заморочиться и написать конверторы (UDF), которые исправят даты еще при импорте. Но все же проще загрузить строки "как есть" и затем неспешно, итерационно, в Jupyterlab notebook отконвретировать простыми командами .astype()

Добрый день!

Действительно, Pandas имеет такую возможность — считать все ячейки как строки.

Проблема в данном случае в том, что Pandas использует OpenPyXL, и, в случае с чтением больших файлов, это огромная трата времени и оперативной памяти и, плюс к этому, дополнительные затраты на конвертацию в строки. Для XLSB сохраняется проблема PyXLSB с чтением дат.

К слову, если используется Pandas старых версий (<2.1.0), он не использует для хранения строк формат PyArrow (как рекомендовано в новых версиях), что приводит к многократному перерасходу оперативной памяти в процессе формирования датафрейма. В новых версиях хорошо использовать read_excel(…, dtype=»string[pyarrow]»).

В новых версиях Pandas добавлена поддержка нового ридера файлов Excel — Calamine (с версии Pandas 2.1 — и, следовательно, как минимум для Python 3.9+, минимальной поддерживаемой версии), который именно заточен на чтение любых файлов Excel (.xlsx,.xls,.xlsb,.ods) — но, опять же, принцип всё тот же: читаем файл строками, потом раскладываем по столбцам, затем конвертируем в строковый тип данных. Тратится оперативная память (строки в любом виде забивают больше памяти, чем числа или даты), и уходит время на конвертацию и «поворот» формата. Хороший момент — что Calamine корректно читает даты в файлах Excel, и в целом работает очень и очень шустро (там Rust «под капотом»), так что, похоже, PyXLSB и OpenPyXL вместе уходят в закат (на зависть пользователям старых версий Pandas/Python и, в том числе, мне).

В целом, мое мнение, файлы XLSX и XLSB, как правило, достаточно хорошо организованы — пусть форматы ячеек не всегда совпадают в пределах столбца, но они обычно относятся к общему типу — в одном столбце даты, в другом строки, в третьем — числа и т. д. По‑настоящему приспособленный для чтения таких файлов инструмент не должен иметь каких‑то особых проблем с соединением таких участков. Но, другая глобальная проблема — наличие «подвалов» и, особенно, «шапок» случайной величины, «лишних» строк — какие‑нибудь «ИТОГ», «СУММА» и т. п. — вставленных непредсказуемым образом — реально заводит в тупик. Также, нет никакого простого способа считать многострочный заголовок, особенно, если он собран местами из «объединенных» (merged) ячеек.

Вот взять, например, десять файлов — в восьми из них шапка занимает 15 строк, и заголовок — 4 строки, в двух оставшихся шапка, внезапно, 16 строк. В одном из первых восьми файлов есть строка итогов внизу таблицы, а в одном из двух оставшихся — итоги вставлены сразу после заголовка… Даже лучшие из существующих инструментов потребуют индивидуальной подгонки параметров для чтения каждого файла, что порождает простыню «одноразового», почти непригодного для переиспользования, кода. Мой же проект предназначен для того, чтобы, по возможности, решить все эти сложности, и при этом оптимизировать траты системных ресурсов.

Возможно, в некоторых случаях будет достаточно Power Query, чтобы объединить данные в один файл.

Добрый день!

Думаю, вы правы, насчет того, что в некоторых случаях, может быть проще прибегнуть к этому мощнейшему инструменту, чтобы объединить файлы в один. Но, мое мнение, если на PyPi есть подходящий для этой задачи инструмент (Pandas в связке с OpenPyXL/PyXLSB или Calamine), на память питониста первым придет именно он, пусть и придется крепко повозиться.

В некоторых же случаях, и в моем случае, в частности, использовать Power Query попросту невозможно.

Почему не кто, не когда, не рассматривает работу с COM напрямую? Для этого есть, например, comtype или pywin32. Извлекать и обрабатывать данные всегда в несколько раз быстрее средствами встроенными в приложение.

Пару лет назад сталкиваясь с базой в Excel, в поисках ответа как с ними работать почти всегда натыкался на pandas + <что то ещё>. Скорость работы таких связок ужасала. Списывал на кривые руки. Сейчас руки вроде не такие кривые, но pandas + <что то ещё> даже на небольшом масcиве (arr < 100 000) это минимум 3 сек. скажем на поиск элемента и извлечение значения, против мгновенного исполнения встроенной в excel функцией find(). Понятно, что api от Макарсофта то ещё древнее чудище, но сейчас эта проблема решается установкой плагина с чатиком. Да, под linux это вроде не работает, но если есть потребность работы с COM то как минимум виртуалку поставить можно.

P.S. pandas распиаренный и всеми любимый, сколько раз не ставил всегда через пару недель сносил нафиг - тупой, неповоротливый, медленный. Если необходимо организовать базу или с dataframe работать, то выгодней sqlite написать, это не одна строчка кода как с pandas, но потом работает гораздо быстрей...

Добрый день!

 

Когда я был еще в процессе поиска инструментов для чтения XLSB файлов, я натыкался на готовые библиотеки для конвертации XLSB -> XLSX. Все они использовали именно COM-интерфейс MS Excel, но мне этот вариант критически не подходил: во-первых, мне нужно было кроссплатформенный модуль, который можно было бы одинаково эффективно использовать и под Windows и под Linux, во-вторых я все такие решения, лично на мой взгляд, являются «костылями» - пусть и доступными, но не универсальными, написанными «чтобы много не писать». И самое главное – я не совсем представляю, как можно настолько упростить взаимодействие с файлами MS Excel, используя такую вещь, как COM интерфейс, чтобы иметь все те же возможности, что и в Polars, например. Полноценный модуль-адаптер для COM интерфейса Excel, скорее всего, окажется по итогу сложнее и медленнее, чем существующие решения.

 

Разумеется, для пользователей MS Excel уровня эксперта – любая задача по плечу, но не думаю, что в нем удобно проводить автоматизацию обработки отчетов и дальнейшую заливку в базу данных. Более того, сомневаюсь, что кто-либо станет для этого ставить виртуалку.

Кроме того, поистине ничтожна вероятность того, что виртуалку Windows можно поставить внутри контейнера Kubernetes с Linux, чтобы «удобно и быстро» разделать файлы Excel командами через SSH терминал :)

 

К слову, недавно успешно отработал с файлом MS Excel – весом 3GB (личный рекорд). 10 листов по 1048000 строк. Помнится, «даже родной» MS Excel такие файлы только открывает +/- вечность. Я сконвертировал их в Parquet, даже не прибегая, собственно, к импорту Pandas или Polars, и теперь, чтобы И открыть любой лист И найти нужное значение – понадобится менее 5 секунд, так что в данном случае RXLS уделывает MS Excel просто в ноль. На моем не особо мощном ПК на конвертацию понадобилось около 15 минут на лист, но я уверен, MS Excel не открыл бы файл вообще – ни сегодня, ни завтра, никогда.

Sign up to leave a comment.

Articles