- Дата публикации
Polars против Pandas: когда пора менять любимую библиотеку для анализа данных
Что нового
Polars — относительно свежий игрок в мире датафреймов, но уже с довольно зрелым набором возможностей:
- Полная реализация на Rust, без внешних зависимостей. Установка через
pip install polarsне тянет за собой ни NumPy, ни PyArrow, ни другие библиотеки. - Поддержка двух режимов работы:
- Pandas-like: сразу выполняет операции и возвращает результат.
- Ленивый режим (Lazy API): сначала строит план вычислений, оптимизирует его, а потом выполняет одной пачкой по команде
collect().
- Опора на формат Apache Arrow: колоночное хранение, совместимость с Arrow-данными, в том числе с операциями без копирования.
- Потоковый API: можно обрабатывать данные по частям, не загружая весь датасет в память.
- Автоматическая параллельная обработка: Polars сам распределяет вычисления по ядрам CPU.
- Векторизованное исполнение запросов.
- Возможность выполнять запросы на GPU с CUDA (NVIDIA), если инфраструктура это позволяет.
- Простая конвертация между Pandas и Polars:
pl.from_pandas(pandas_df)polars_df.to_pandas()
Автор исходного текста — Senior Data Scientist из Яндекса — подчёркивает, что Polars уже удобно использовать в реальных пайплайнах и при этом он заметно устойчивее к падениям ядра при работе с большими датасетами по сравнению с привычным стеком на Pandas.
Как это работает
Архитектура и формат данных
Polars опирается на колоночное представление данных, совместимое с Apache Arrow:
- Данные в памяти лежат по столбцам, а не по строкам.
- Это ускоряет операции по столбцам (агрегации, фильтры, вычисления признаков) и уменьшает объём данных, которые нужно читать из памяти.
- Polars умеет принимать и отдавать Arrow-данные, часто без копирования.
При этом Polars не использует PyArrow как движок вычислений. Вся работа с памятью и исполнение запросов реализованы внутри Polars на Rust.
Типы данных и объекты
Polars предлагает знакомые по Pandas сущности и добавляет свои:
DataFrame— основной табличный объект.Series— столбец данных.LazyFrame— ленивый датафрейм, который хранит не сами данные, а план вычислений.Schema— структура датафрейма: названия столбцов и их типы.
Примеры перехода между форматами:
polars_df = pl.from_pandas(pandas_df) # Polars DataFrame
pandas_df = polars_df.to_pandas() # Pandas DataFrame
Переход к ленивому режиму и обратно:
lazy_polars_df = polars_df.lazy() # LazyFrame
polars_df = lazy_polars_df.collect() # DataFrame
Проверка схемы:
print(polars_df.schema)
# Schema({'name': String, 'birthdate': Date, 'weight': Float64, 'height': Float64})
Lazy API и оптимизатор запросов
Главная техническая фишка Polars — Lazy API. Когда вы пишете цепочку операций, библиотека не выполняет их по шагам. Она собирает:
- План вычислений (
LazyFrame). - Прогоняет его через оптимизатор запросов.
- Выполняет уже оптимизированный план при вызове
collect().
Пример:
q = (
pl.scan_csv("../data/iris.csv")
.filter(pl.col("sepal_length") > 5)
.group_by("species")
.agg(pl.col("sepal_width").mean())
)
df = q.collect()
Polars позволяет заглянуть внутрь плана и понять, что он собирается делать:
print(q.explain())
Оптимизатор делает несколько важных вещей:
- Раннее применение фильтров — по возможности уже на этапе чтения файла.
- Projection pushdown — читает только нужные столбцы с диска.
- Срез на уровне сканирования — загружает только необходимую часть данных.
- Оптимизация порядка join-ов — уменьшает пиковое потребление памяти.
- Автоматическое приведение типов — подбирает совместимые типы с минимальным расходом памяти.
Вместе с параллельным исполнением и векторизацией это даёт серьёзный выигрыш по скорости и устойчивости на больших объёмах данных.
Что это значит для вас
Когда Pandas уже не тянет
Если вы видели в Jupyter надпись Kernel crashed после попытки прочитать или агрегировать большой CSV — вы целевая аудитория Polars.
Polars особенно полезен, когда:
- Датасеты не помещаются целиком в память или находятся на грани по размеру.
- Вы строите сложные пайплайны с большим количеством фильтров, join-ов и агрегаций.
- Нужна максимальная скорость обработки на одном сервере без разворачивания кластера Spark.
- Важна простая установка без конфликта зависимостей.
Типичные сценарии, где Polars помогает
- Разведочный анализ данных (EDA) по большим логам, кликам, телеметрии.
- Подготовка фичей для моделей машинного обучения, когда датасеты уже не игрушечные.
- Обработка данных из data lake (S3, облачные хранилища, базы данных) с минимальными затратами памяти.
- Построение аналитических пайплайнов, где важна повторяемость и понятный план выполнения.
Где можно остаться на Pandas
Pandas по‑прежнему удобен, если:
- Вы работаете с небольшими датасетами, которые уверенно помещаются в память.
- Важна экосистема вокруг Pandas: специфичные плагины, редкие типы индексов, плотная интеграция с существующим кодом.
- Команда уже глубоко завязана на Pandas, а переезд на Polars сейчас не окупает время.
Хороший практический подход:
- Не выбрасывать Pandas, а добавить Polars в стек.
- Использовать Polars там, где вы уже упёрлись в производительность или память.
- Спокойно конвертировать датафреймы туда‑обратно, когда нужно использовать сторонние библиотеки только с Pandas.
Ограничения и реалии использования
- Polars написан на Rust, но для Python-разработчика это прозрачно: API очень похож на Pandas, но местами более декларативный.
- Для полноценной работы на GPU нужны NVIDIA и CUDA. Без этого Polars будет работать только на CPU — но уже с серьёзным выигрышем за счёт Rust и оптимизатора.
- Библиотека активно развивается, поэтому иногда меняются детали API. Это плюс по скорости развития, но минус, если нужен «замороженный» интерфейс на годы.
Polars распространяется как обычный Python-пакет. Ограничений по региону использования нет, VPN не нужен.
Место на рынке
Если смотреть на Polars через призму привычных инструментов анализа данных, картинка выглядит так:
- Pandas — стандарт де-факто для Python-аналитики, с огромной экосистемой и документацией. Но он исторически ориентирован на работу в памяти и не оптимизирован под ленивые вычисления и сложную оптимизацию планов запросов.
- Polars — альтернатива для тех же задач, но с другим приоритетом: скорость, экономия памяти, параллельность и ленивое исполнение.
Ключевые отличия Polars от Pandas:
- Реализация на Rust, а не на Python + C.
- Колонночное хранение и совместимость с Apache Arrow.
- Lazy API с оптимизатором запросов.
- Возможность стриминга данных без загрузки всего датасета в память.
- Автоматическая параллельная обработка без ручной настройки.
Экосистема вокруг Pandas пока шире, но Polars закрывает другой класс проблем: он помогает там, где Pandas начинает тормозить или падать при росте объёма данных.
Установка
Polars ставится одной командой и не требует дополнительных библиотек:
pip install polars
Импорт по соглашению:
import polars as pl
Технически вы можете написать и так:
import polars as pandas
Но это только запутает код и коллег. Логичнее придерживаться import polars as pl.
Как запустить: базовые примеры
Переход между Pandas и Polars
import pandas as pd
import polars as pl
# Pandas DataFrame
pandas_df = pd.DataFrame({
"name": ["Alice", "Bob"],
"age": [25, 30]
})
# В Polars
polars_df = pl.from_pandas(pandas_df) # Polars DataFrame
# Обратно в Pandas
pandas_df_back = polars_df.to_pandas() # Pandas DataFrame
Lazy API: чтение, фильтрация, агрегация
import polars as pl
q = (
pl.scan_csv("../data/iris.csv")
.filter(pl.col("sepal_length") > 5)
.group_by("species")
.agg(pl.col("sepal_width").mean())
)
# Выполнить запрос и получить DataFrame
df = q.collect()
# Посмотреть план выполнения и оптимизации
print(q.explain())
Работа со схемой
polars_df = pl.DataFrame({
"name": ["Alice", "Bob"],
"birthdate": [
pl.date(1990, 1, 1),
pl.date(1985, 6, 15)
],
"weight": [55.5, 80.2],
"height": [165.0, 180.5]
})
print(polars_df.schema)
# Schema({'name': String, 'birthdate': Date, 'weight': Float64, 'height': Float64})
Итоговый совет
Если вы делаете аналитику или Data Science и уже ловили падения ядра или мучительно ждали, пока Pandas «переварит» большой CSV, имеет смысл поставить Polars и попробовать перенести типичный пайплайн на Lazy API. Порог входа для тех, кто знает Pandas, низкий, а выигрыш по скорости и памяти на больших данных может быть критичным для продуктивной работы.