Pandas была стандартной Python-библиотекой для анализа данных более десяти лет. В 2026 году она по-прежнему повсюду — но уже не является очевидным выбором. Новое поколение библиотек предлагает кардинально лучшую производительность, меньшее потребление памяти и более интуитивные API.

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

Участники сравнения

БиблиотекаЗрелостьНаписана наГлавное преимущество
Pandas 2.2ЗрелаяC/PythonЭкосистема, знакомство
Polars 1.xСтабильнаяRustСкорость, эффективность памяти
DuckDB 1.xСтабильнаяC++SQL-интерфейс, zero-copy
ModinСтабильнаяPythonDrop-in замена Pandas
VaexПоддержкаC++/PythonOut-of-core обработка
DataFusion (Python)РастущаяRustНативная поддержка Apache Arrow

Производительность: что показывают бенчмарки

Вместо того чтобы выдумывать числа, вот что демонстрируют официальные и сторонние бенчмарки:

Бенчмарк Polars PDS-H (на основе TPC-H)

Команда Polars поддерживает open-source набор бенчмарков, основанный на бенчмарке поддержки принятия решений TPC-H, под названием PDS-H. Последние результаты (май 2025) сравнивают Polars с Pandas и другими движками на стандартизированных аналитических запросах.

Ключевые выводы из официального бенчмарка:

  • Polars стабильно превосходит Pandas с существенным отрывом по всем 22 запросам на основе TPC-H
  • Polars использует значительно меньше памяти, чем Pandas для эквивалентных операций
  • Бенчмарк имеет открытый исходный код на GitHub, поэтому результаты воспроизводимы

Исследование энергопотребления и производительности

Отдельное исследование энергетических бенчмарков Polars показало, что Polars потребляет примерно в 8 раз меньше энергии, чем Pandas при синтетических задачах анализа данных с большими DataFrame, и использует около 63% энергии, требуемой Pandas для запросов типа TPC-H на больших наборах данных.

Общие характеристики производительности

На основе опубликованных бенчмарков и отчётов сообщества:

  • Polars и DuckDB значительно быстрее Pandas для большинства аналитических операций, особенно на наборах данных свыше 1М строк
  • DuckDB особенно силён на нагрузках с интенсивными агрегациями и соединениями
  • Modin даёт умеренное ускорение по сравнению с Pandas, но ценой большего потребления памяти
  • Pandas 2.x с типами данных на базе Arrow заметно быстрее Pandas 1.x

Примечание: точные соотношения производительности сильно зависят от оборудования, структуры данных и сложности запросов. Всегда тестируйте на своих рабочих нагрузках.


Polars — новый стандарт для задач, критичных к производительности

Для новых проектов, где производительность важна, Polars стал ведущей альтернативой Pandas.

import polars as pl

df = pl.read_parquet("events.parquet")

result = (
    df.lazy()
    .filter(pl.col("event_type") == "purchase")
    .group_by("user_id")
    .agg([
        pl.col("amount").sum().alias("total_spent"),
        pl.col("amount").count().alias("num_purchases"),
    ])
    .sort("total_spent", descending=True)
    .head(100)
    .collect()
)

Почему Polars выделяется:

  • Значительно быстрее Pandas в большинстве операций — подтверждено официальными бенчмарками PDS-H (источник)
  • Ленивые вычисления оптимизируют план запроса перед выполнением. Написание .lazy() в начале и .collect() в конце — самая важная доступная оптимизация производительности
  • Последовательный API без многочисленных подводных камней Pandas (SettingWithCopyWarning, знакомо?)
  • На Rust с настоящим параллелизмом — по умолчанию использует все доступные ядра

Честные недостатки:

  • Пробелы в экосистеме: многие библиотеки по-прежнему ожидают DataFrame из Pandas. Конвертация через .to_pandas() иногда неизбежна
  • Интеграция с визуализацией слабее — Matplotlib/Seaborn ожидают входные данные из Pandas
  • API достаточно отличается, чтобы создать реальную кривую обучения. Командам с опытом работы с Pandas стоит заложить примерно неделю на переход

DuckDB — когда SQL является предпочтительным интерфейсом

DuckDB — это не библиотека DataFrame, а встраиваемая аналитическая база данных. Но она стала одним из лучших способов анализа данных в Python.

import duckdb

result = duckdb.sql("""
    SELECT 
        user_id,
        SUM(amount) as total_spent,
        COUNT(*) as num_purchases
    FROM read_parquet('events.parquet')
    WHERE event_type = 'purchase'
    GROUP BY user_id
    ORDER BY total_spent DESC
    LIMIT 100
""").fetchdf()

Почему DuckDB убедителен:

  • Отличная производительность агрегаций — на уровне или быстрее Polars в операциях groupby и join
  • Zero-copy интеграция с Pandas, Polars и Arrow. SQL-запросы могут обращаться к DataFrame из Pandas без копирования данных
  • Читает Parquet, CSV, JSON напрямую — не нужен явный этап загрузки
  • Встраиваемая — без сервера, без настройки, просто pip install duckdb

Когда выбирать DuckDB вместо Polars:

  • Команде удобнее работать с SQL, чем с цепочками методов
  • Нужно запрашивать файлы напрямую без построения пайплайна
  • Нужно объединять данные из разных форматов (CSV + Parquet + JSON)

Когда Polars — лучший выбор:

  • Сложные многоэтапные преобразования (цепочки методов обычно читаемее вложенного SQL)
  • Построение пайплайнов обработки данных на Python
  • Когда нужен тонкий контроль над выполнением

Pandas 2.2 — всё ещё актуален (с оговорками)

Pandas не умер. С типами данных на базе Arrow в версии 2.x он значительно быстрее Pandas 1.x:

import pandas as pd

# Использовать типы Arrow для лучшей производительности
df = pd.read_parquet("events.parquet", dtype_backend="pyarrow")

По-прежнему выбирать Pandas, когда:

  • Команда уже хорошо его знает и производительность достаточна
  • Нужна максимальная совместимость с библиотеками (scikit-learn, statsmodels и др.)
  • Работа с небольшими наборами данных (<1М строк), где разница в производительности незначительна
  • Разведочный анализ в Jupyter-ноутбуках

Рассмотреть альтернативы, когда:

  • Наборы данных превышают доступную оперативную память
  • Строятся продакшн-пайплайны, где производительность важна
  • Регулярная работа с наборами данных свыше 10М строк

Modin — сложная рекомендация

Modin обещает ускорить Pandas, изменив одну строку импорта. На практике компромиссы значительны:

  • Больший расход памяти, чем у самого Pandas (данные распределяются между процессами)
  • Неполное покрытие API — некоторые операции молча откатываются к Pandas
  • Накладные расходы на запуск делают его медленнее для малых наборов данных
  • Сложность отладки возрастает при проблемах с распределённым выполнением

Оценка: Для большинства команд лучше либо остаться с Pandas (ради совместимости), либо перейти на Polars (ради производительности). Modin занимает неудобную промежуточную позицию, которая не полностью удовлетворяет ни одной из целей.


Схема принятия решения

Данные < 1М строк?
  → Pandas (с типами Arrow) справится. Не усложняйте.

Команда предпочитает SQL?
  → DuckDB.

Строите пайплайн обработки данных на Python?
  → Polars.

Нужно запрашивать файлы без их загрузки?
  → DuckDB.

Данные > 100М строк на одной машине?
  → Polars (lazy mode) или DuckDB.

Данные больше доступной оперативной памяти?
  → DuckDB или Polars (потоковый режим).

Дополнительные материалы

Есть вопросы о миграции с Pandas? Пишите на [email protected].