Все начинается со скромного стола. Концепция, которая никогда не была по-настоящему изобретена, поскольку она постоянно совершенствовалась на основе самых ранних форм ведения учета. Даже сегодня — вернее, особенно сегодня — методы хранения и преобразования данных в таблицах продолжают развиваться. От реляционных баз данных, таких как PostgreSQL, которые являются более функциональными, чем когда-либо, до чрезвычайно масштабируемых решений для уменьшения карты, таких как Dask или Spark. И, конечно же, почтенный Spreadsheet.

Но вернемся к вашему затруднительному положению: вы хотите работать на Python и сохранять простоту, поэтому никаких автономных SQL или распределенных систем. В этом случае есть все рамки данных и таблицы данных на выбор. Давайте сравним четыре популярных: Pandas (действующий оператор), Polars (претендент), PyArrow (низкоуровневый столбец) и DuckDB (внутрипроцессный/встроенный аналитический SQL).

Документы и экосистема

Как и в случае с любой новой библиотекой, которую стоит опробовать, большое значение имеют простота использования и скорость, с которой вы сможете начать работу. Сильнейшими соперниками в этом отношении являются Pandas и DuckDB. Pandas имеет огромную экосистему документации, руководств и тем вопросов и ответов. И если какой-то тип данных не встроен, есть большая вероятность, что кто-то уже написал для него библиотеку. То, как DuckDB сравнивается, зависит от вашего знакомства с SQL (ознакомьтесь с нашей предыдущей записью в блоге для получения некоторого контекста). Для тех, кто знаком с древними заклинаниями, вероятно, будет быстрее начать работу, чем с пандами. Вдвойне, учитывая богатую документацию DuckDB.

Polars также подробно документирован. Но он не может конкурировать с Pandas в плане экосистемы и поддержки (у него более чем в 200 раз меньше вопросов на StackOverflow). Сообщения об ошибках от Polars также могут иногда быть довольно загадочными из-за используемых дополнительных уровней абстракции (Rust и Arrow). Все это делает эксперименты для начинающих пользователей немного сложнее.

Наконец, PyArrow намеренно является фреймворком более низкого уровня. Это в значительной степени предназначено в качестве строительного блока для других библиотек. Это отражено в документации, которая более техническая и менее учебная. Если вы готовы приложить усилия, это особенно мощный инструмент.

Должен идти быстро

Панды могут бегать только со скоростью около 30 км/ч, так что они не могут сравниться со скоростью полета 80 км/ч+, которую могут развивать некоторые утки… Ах, подождите, нет, библиотеки Python, а не фауна. Попробуем еще раз.

Используя примерно 2,5 ГБ / 8 500 000 строк данных о наблюдениях за птицами с таксономической информацией, я провел несколько эталонных тестов для четырех библиотек. Первый тест выполняет простую групповую операцию, подсчитывая количество наблюдений за видом, используя часть набора данных. На моей машине (M2 Pro MacBook, 16 ГБ ОЗУ) это преобразование занимает примерно 60 миллисекунд с PyArrow, 130 с Polars и 160 с DuckDB. Тем не менее, Pandas представляет собой интересный случай: при использовании движка c по умолчанию он, безусловно, самый медленный, его выполнение занимает более 1,6 секунды. Однако, используя свой экспериментальный движок PyArrow, результаты ждут встряски: Pandas побеждает всех, кроме PyArrow, занимая всего 80 мс. Хотя абсолютные числа не имеют большого значения, относительная разница между библиотеками весьма показательна. Это также хорошо подходит для других простых операций и небольших наборов данных.

Глядя на более сложное преобразование, использующее всю таблицу таксономии, все немного меняется. Второй тест выполняет два объединения и некоторые вычисления столбцов, подсчитывая количество наблюдений для каждого вида на таксон и в пределах определенной географической области. К сожалению, здесь пока нельзя использовать движок PyArrow; поэтому вам просто нужно представить, что Pandas с PyArrow будут работать так же, как Polars здесь [1].

Однако общая картина обоих тестов одинакова: производительность Polars, DuckDB и, вероятно, Pandas с PyArrow сопоставима, в то время как Pandas с движком по умолчанию намного медленнее. Для очень маленьких наборов данных эта разница может быть незначительной. Но для средних наборов данных, таких как этот, и особенно для больших наборов данных или повторяющихся задач, влияние может быть значительным.

Также рекомендуется использовать библиотеку более высокого уровня, такую ​​как Polars или DuckDB, вместо PyArrow, потому что последний требует гораздо большего внимания для оптимизации производительности. Соответственно, большинство видов водоплавающих птиц в районе офиса Dataroots’ Leuven относятся к семейству утиных/гусиных/лебединых. А белых медведей здесь нет совсем. Для меня это звучит как научное доказательство того, что DuckDB — это путь 🤷.

Код Комфорт

Наконец, давайте посмотрим на интерфейс, предоставляемый библиотеками. Pandas имеет самую большую поверхность API, часто предлагая несколько способов для достижения одного и того же результата [4]. По моему опыту, это помогает найти решение путем перебора, но также может сбить с толку и привести к несогласованному коду. Polars более самоуверенна в этом отношении, предлагая согласованный и предсказуемый API (Polars Philosophy). Хотя иногда код Polars может быть более подробным, в результате он может быть более читабельным. Как вы могли догадаться из названия, он, конечно же, заимствует большинство концепций у Pandas, поэтому, если вы уже знакомы с Pandas, вы будете чувствовать себя как дома. В противном случае кривая обучения, вероятно, будет более крутой.

Что касается PyArrow: его низкоуровневое ядро ​​​​Arrow действительно просвечивает. Это побуждает вас мыслить таким же ориентированным на столбцы способом, каким данные обрабатываются внутри. Операции с вашими данными также более явные, что — к лучшему или к худшему — раскрывает абстракции, предоставляемые библиотеками более высокого уровня.

Единственным интерфейсом DuckDB является SQL: вероятно, это глоток свежего воздуха для многих в сообществе специалистов по данным. Вы можете использовать свои существующие знания SQL без необходимости изучать еще одну платформу. Если вы еще не знакомы с SQL, это также может быть ситуация, когда стакан наполовину полон, поскольку вы осваиваете особенно полезный навык. Кроме того, использование DuckDB в вашей кодовой базе помогает сократить разрыв между аналитиками данных и инженерами благодаря общему языку.

Имея все это в виду, давайте закончим простым примером всех четырех:

"""Add a column to a table indicating whether a bird is of
the Anatidae family (ducks, geese, and swans)."""

# Pandas (with PyArrow)
import pandas as pd

df = pd.read_csv(
    "bird_spot.csv",
    engine="PyArrow",
    dtype_backend="PyArrow"
)
df["is_anatidae"] = df["family"] == "anatidae"

# Polars
import polars as pl

df = pl.read_csv("bird_spot.csv")
df = df.with_columns([
    (pl.col("family") == "anatidae").alias("is_anatidae")
])

# PyArrow
import pyarrow.csv
import pyarrow.compute as pc

table = pyarrow.csv.read_csv("bird_spot.csv")
table = table.append_column(
    "is_anatidae",
    pc.equal(table["family"], "anatidae")
)

# DuckDB
import duckdb

table = duckdb.query("""
    SELECT *, family = 'anatidae' AS is_anatidae
    FROM read_csv_auto('bird_spot.csv')
""").fetchall()

Заключение

Надеюсь, я удовлетворил ваше любопытство к преобразованиям таблиц Python за пределами стандартной библиотеки. Для краткого обзора обсуждаемых вариантов, вот мое личное мнение: для образовательных целей и случаев, когда расширяемость имеет первостепенное значение, Pandas по-прежнему является отличным выбором. И как только PyArrow станет стандартом по умолчанию, он может снова править. Если вы предпочитаете легкий путь к производительности при почти такой же простоте использования, выберите Polars для своего следующего проекта с нуля. Если вы ищете низкоуровневую библиотеку для дальнейшего развития (например, для создания библиотеки преобразований типа «укажи и щелкни»), PyArrow может подойти. . И если вы ищете сочетание скорости от Polars с повсеместностью и доступностью SQL, DuckDB действительно непревзойденный.

Но самое главное, попробуйте сами! Есть много того, что я даже не упомянул (например, datatable H2O.ai, Modin, ClickHouse). И вы всегда можете попробовать совершенно другой язык: может быть, попробовать DataFrames или R Джулии.

[0]: Характерное изображение под лицензией CC BY-SA 3.0. Ремикс изображения панды из Ailuropoda melanoleuca -San Diego Zoo -upper body-8a от randychiu под CC BY 2.0. Ремикс изображения белого медведя из Polar Bear — Alaska (cropped) Алана Уилсона в рамках CC BY-SA 3.0. Ремикс изображения утки из Утка-самец кряквы 2 от Alain Carpentier в соответствии с Лицензией свободной документации GNU, версия 1.2. Изображение рыбы-лучника, ремикшированное из Toxotes jaculatrix от Chumps в соответствии с Лицензией свободной документации GNU, версия 1.2.
[1]: CSV-файлы, необходимые для сложного преобразования, требуют специальной цитаты. Обработке см. Pandas issue #52266 по этому поводу.
[2]: хотя и спекулятивно, изменение порядка между PyArrow, Polars и DuckDB может быть связано с оптимизацией более высокого уровня, которую могут выполнять последние два. Низкоуровневый доступ, который предоставляет PyArrow, является палкой о двух концах в этом отношении, позволяя, но также требуя ручной оптимизации, чтобы выжать последнюю каплю производительности. Дополнительные тесты также можно найти в базе данных от H2O.ai (создатели datatable).
[3]: Если вы хотите ускорить существующий проект Pandas, основанный на NumPy или его движке Python, не прибегая к переключению между фреймворками, рассмотрите возможность использования Cython или Numba. См. раздел Повышение производительности в документации.
[4]: ​​Возможно, временами мешает дзен Python.

Вам также может понравиться

Пасти стадо с MotherDuck: ваше следующее хранилище данных? — Сэм Дебрюйн

В Dataroots нас заинтриговал новый путь, по которому сообщество данных идет с DuckDB. Вы можете послушать наш подкаст или прочитать нашу предыдущую запись в блоге на эту тему. Чтобы немного освежить вашу память: DuckDB — это внутрипроцессный OLAP. Это похоже на то, что делает SQLite для рабочих нагрузок OLTP. DuckDB — это…

datarootsdataroots