Polars 1.x в Python: Пълно ръководство за DataFrame, LazyFrame и Streaming (2026)
Практическо ръководство за Polars 1.x в Python: мързелив оптимизатор, streaming engine, миграция от Pandas и интеграция със scikit-learn с реални примери и бенчмаркове за 2026.
Polars е бърза колонна DataFrame библиотека за Python, написана на Rust и базирана на Apache Arrow, която обработва до 30 пъти по-бързо групиране, филтриране и join операции в сравнение с Pandas. Причината е проста: многоядрено изпълнение и мързелив оптимизатор на заявки. В това ръководство за 2026 ще научите как работи Polars 1.x, как да мигрирате от Pandas, кога да включите streaming engine и как да интегрирате Polars със scikit-learn в реален ML пайплайн.
Честно казано, първия път когато преминах един ETL job от Pandas към Polars, си помислих, че съм счупил измерването. Пет минути се превърнаха в 12 секунди. Оттогава Polars е първата ми опция за нови pipeline-и.
Polars 1.39 (март 2026) стабилизира streaming engine с merge join и AsOf join, което позволява обработка на набори от данни, които не се събират в RAM.
LazyFrame API прилага predicate pushdown, projection pushdown и operation fusion, което често прави заявките 5–30× по-бързи от Pandas.
Всички операции използват всички налични CPU ядра по подразбиране, без нужда от ръчен паралелизъм.
Миграцията от Pandas е плавна: pl.from_pandas() и .to_pandas() са zero-copy за числови колони.
Pandas 3.0 премина на PyArrow за низове, но Polars запазва предимство при аналитични заявки над 100K реда.
Използвайте Polars за нови ETL пайплайни и Pandas при границата с scikit-learn или библиотеки, които не разбират Arrow.
Какво е Polars в Python?
Polars е DataFrame библиотека, написана на Rust, която експонира първокласен Python API за анализ на структурирани данни. Ritchie Vink стартира проекта през 2020 г. с изричната цел да замести Pandas за workloads, където производителността, паметта и предвидимостта на типовете имат значение. Първата стабилна 1.0 версия излезе през 2024 г. До август 2026 г. проектът е достигнал 1.43, с 12 релийза само през първото тримесечие и над 95 активни contributors.
Тъй като библиотеката е базирана на колонния формат Apache Arrow, данните ви живеят в непрекъснати блокове памет, оптимизирани за vectorized операции. За разлика от Pandas, който използва NumPy и Python-центричен модел, Polars може да чете колона от 100 милиона реда, без да сериализира стойностите в Python обекти. Това е основата за автоматичното многоядрено изпълнение (всяка операция се разцепва между всички физически ядра), без вие да пишете нито ред многонишков код.
Polars предлага два режима на изпълнение: eager (изпълнение веднага, като Pandas) и lazy (изгражда логически план на заявката, оптимизира го и го изпълнява при .collect()). Lazy режимът е препоръчителният по подразбиране за production, защото само тогава оптимизаторът може да пренарежда филтри, да отхвърля колони и да слива операции в един проход.
Polars срещу Pandas 2026: сравнителна таблица и бенчмаркове
На тестове с 240 милиона реда Polars показва 10× ускорение при group-by и joins, до 11× при sort и filter, и 4.7× при четене на Parquet. За обикновени 10-милионни таблици типичното време на Pandas е около 5–6 секунди, докато Polars приключва под 250 милисекунди. Разликата е най-голяма при lazy режим и wide таблици, където projection pushdown отсява неизползвани колони още при отваряне на файла.
Характеристика
Polars 1.43
Pandas 3.0
Език на имплементация
Rust
Python + C (NumPy)
Формат в паметта
Apache Arrow (columnar)
NumPy + PyArrow за низове (от 3.0)
Изпълнение
Eager + Lazy + Streaming
Само eager
Threading
Многоядрено по подразбиране
Едноядрено
Оптимизатор на заявки
Да (predicate/projection pushdown)
Не
Липсващи стойности
Само null
NaN, NA, None
Обработка извън паметта
Да (streaming engine)
Само на части чрез chunking
Бенчмарк 240M реда group-by
~3 сек
~30 сек
Pandas 3.0 направи PyArrow задължителна зависимост и превключи низовите колони на PyArrow-backed strings, което е най-голямото производителностно подобрение от версия 2.0 насам. Въпреки това, при аналитични заявки на 100K+ реда Polars все още е значително по-бърз, особено при lazy режим. За допълнителни съвети как да ускорите съществуващите Pandas пайплайни, вижте нашето ръководство за инженеринг на признаци с Pandas и scikit-learn.
Инсталиране на Polars и първи DataFrame
Polars 1.x работи на Python 3.9+ и се разпространява като wheel за всички основни платформи. Инсталирайте базовия пакет с pip или uv:
# Основна инсталация
pip install "polars>=1.39"
# С pyarrow за zero-copy връзка с Parquet/Arrow
pip install "polars[pyarrow]"
# Плюс SQL интерфейс, XLSX и Delta Lake
pip install "polars[all]"
За системи с CPU без AVX2 (например по-стари сървъри) използвайте polars-lts-cpu. Ако използвате uv, командата е uv add polars[pyarrow]. За среди с GPU Polars предлага експериментален NVIDIA cuDF backend, който активирате с engine="gpu" при .collect().
Синтаксисът е сходен с Pandas, но има една ключова разлика. Изразът pl.col("цена") е израз, а не низ, и може да участва във верижни операции без Python overhead. Малка разлика на пръв поглед, но точно оттук идва цялото ускорение.
Expression API: концепция и примери
Изразите (expressions) са гръбнакът на Polars. Всеки израз описва трансформация на колона (или няколко колони) и се изпълнява от Rust ядрото, без да минава през Python интерпретатора за всяка стойност. Това ги прави хиляди пъти по-бързи от еквивалентните DataFrame.apply(lambda ...) в Pandas. Това е и основната причина, поради която Polars може да разцепи една агрегация между всички CPU ядра автоматично.
Обърнете внимание, че всички агрегации се пресмятат за един проход през данните. Polars групира израза, планира какви колони са нужни и разпределя работата между наличните ядра. За условна логика използвайте pl.when(...).then(...).otherwise(...):
Този подход замества чисто Python if/else вериги и запазва работата векторизирана. За допълнителна статистическа обработка Polars разбира и повечето операции, които ще срещнете в нашето ръководство за статистически анализ и тестване на хипотези.
LazyFrame и оптимизаторът на заявки: как работи
LazyFrame е абстракция, която не изпълнява операциите веднага, а гради логически план. Когато извикате .collect(), оптимизаторът анализира целия план и прилага серия от трансформации преди действителното изпълнение. Според официалната документация на Polars, най-важните оптимизации са:
Predicate pushdown. Филтрите се преместват колкото се може по-рано, дори до нивото на файловия scanner, така че редовете, които не отговарят, никога не се четат.
Projection pushdown. Неизползваните колони се изхвърлят при отваряне на файла, а не в паметта.
Operation fusion. Няколко последователни трансформации се обединяват в един проход върху данните.
Common subexpression elimination. Повтарящи се подизрази се пресмятат само веднъж.
import polars as pl
# Lazy pipeline — нищо не се изпълнява до .collect()
q = (
pl.scan_parquet("s3://моят-бъкет/логове-2026/*.parquet")
.filter(pl.col("код") == 500)
.filter(pl.col("timestamp") >= "2026-08-01")
.select(["ендпойнт", "latency_ms", "user_id"])
.group_by("ендпойнт")
.agg([
pl.col("latency_ms").quantile(0.99).alias("p99"),
pl.col("user_id").n_unique().alias("засегнати"),
])
.sort("p99", descending=True)
)
# Прегледайте оптимизирания план преди изпълнение
print(q.explain(optimized=True))
# Изпълнете
df = q.collect()
Извиквайки .explain(optimized=True), ще видите как Polars е преместил филтрите преди четенето на файловете и е отхвърлил колоните, които не участват в резултата. За S3, GCS и Azure Blob посочете storage_options={"aws_access_key_id": ..., "aws_secret_access_key": ...}. От версия 1.43 Polars стриймва директно от cloud, без първо да сваля целия файл.
Streaming engine в Polars 1.39: обработка на данни, които не се събират в паметта
Streaming engine позволява изпълнение на заявки на batches, така че наборите от данни, които не се събират в RAM, могат да се обработват без crash. Според официалните release notes за Polars 1.39 (12 март 2026), новата streaming engine добавя merge join (в 1.38) и AsOf join (в 1.39). Версия 1.40 добави и групиран AsOf join, а 1.43 разшири streaming за Hive-partitioned източници.
Ето как включвате streaming в заявка:
import polars as pl
q = (
pl.scan_csv("огромен-файл-50gb.csv")
.filter(pl.col("state") == "active")
.group_by("customer_id")
.agg([
pl.col("amount").sum(),
pl.col("order_id").count(),
])
)
# Изпълнение чрез streaming engine
df = q.collect(engine="streaming")
# Или глобално, за цялата програма:
pl.Config.set_engine_affinity("streaming")
Streaming engine е не само по-икономичен откъм памет, но често и по-бърз от in-memory engine, защото използва по-модерни векторизирани kernel-и. Полярният екип препоръчва да бъде включен по подразбиране в 2026 г. и вероятно ще стане стандартен engine в следваща major версия.
Ако пишете резултата обратно на диск, използвайте sink_parquet, sink_ipc или sink_csv. Те стриймват записа и не буферират цялата таблица в паметта:
Един от най-често цитираните ползи на Polars е паралелният group_by. При Pandas, дори с PyArrow backend, group-by работи на едно ядро. Polars разцепва хеш таблицата между всички ядра, което дава почти линейно ускорение. На 16-ядрен CPU агрегация над 100M реда приключва под 2 секунди. Същата операция в Pandas ми отнема над минута на същия хардуер.
Joins в Polars също са паралелни. Поддържат се inner, left, outer, semi, anti, cross и as-of join (за времеви серии, където съответствието е "най-близък по-малък ключ"). AsOf join е особено ценен за финансови данни, където съпоставяте tick-ове с котировки:
Ако мигрирате съществуващ Pandas код, следните разлики обикновено предизвикват най-много объркване:
Без index. Polars няма концепция за row index (редовете са позиционни). Ако вашият Pandas код разчита на df.set_index("date"), преформатирайте го към df.sort("date") плюс филтри по колона.
Строги типове. Polars не позволява имплицитни конверсии, не можете да смесите int и str в една колона. Това предотвратява много от суптилните грешки в Pandas.
Само null. Няма разлика между NaN, NA и None. Проверявайте с .is_null(), а не с .isna().
Без inplace=True. Всяка операция връща нов DataFrame. Присвоете обратно: df = df.with_columns(...).
Изрази вместо колони като списъци. Използвайте pl.col("x") + pl.col("y"), а не df["x"] + df["y"], за да останете във векторизираното ядро.
Method chaining е предпочитан. Дълги chain-ове от операции позволяват на оптимизатора да види целия pipeline и да го препише.
Интеграция със scikit-learn, Matplotlib и Arrow екосистемата
Повечето scikit-learn естиматори очакват NumPy масиви или Pandas DataFrame. Polars предлага .to_pandas() и .to_numpy(), и двата zero-copy за числови колони благодарение на общия Arrow буфер. Препоръчаният pattern е ясен: Polars за предварителна обработка, конверсия на границата, fit с scikit-learn. Този подход комбинира скоростта на Polars за ETL с богатата ML екосистема на Pandas/NumPy. Вписва се естествено и в scikit-learn Pipeline подхода.
import polars as pl
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.model_selection import train_test_split
# ETL с Polars — бърз и паралелен
raw = pl.scan_parquet("сделки.parquet")
features = (
raw
.filter(pl.col("статус") == "затворена")
.with_columns([
pl.col("сума").log().alias("log_сума"),
(pl.col("завършване") - pl.col("създаване")).dt.total_seconds().alias("продължителност"),
])
.select(["log_сума", "продължителност", "тип_клиент", "печалба"])
.collect(engine="streaming")
)
# Конверсия на границата с scikit-learn
X = features.select(pl.exclude("печалба")).to_pandas()
y = features["печалба"].to_numpy()
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
model = GradientBoostingClassifier().fit(X_train, y_train)
За визуализация Polars работи безпроблемно с Matplotlib, Seaborn, Plotly и Altair. Просто извикайте .to_pandas() преди sns.lineplot(), или ползвайте директно plotly.express, който поддържа Polars DataFrame нативно от версия 5.20. Вижте нашето ръководство за визуализация с Matplotlib и Seaborn за конкретни рецепти.
Polars също така интеропира с DuckDB, Delta Lake и Iceberg. Всички те говорят Arrow, така че прехвърлянето между тях е практически безплатно. Това прави Polars идеална "лепилна" библиотека в модерен lakehouse pipeline: Polars за трансформации, DuckDB за ad-hoc SQL и Delta/Iceberg за версионирано съхранение.
Често задавани въпроси
Какво е Polars и с какво се отличава от Pandas?
Polars е колонна DataFrame библиотека, написана на Rust и базирана на Apache Arrow. За разлика от Pandas, тя работи многоядрено по подразбиране, поддържа мързелив оптимизатор на заявки и streaming engine за данни, които не се събират в паметта, което често дава 5–30× ускорение при аналитични заявки.
По-бърз ли е Polars от Pandas 3.0?
Да. Дори след като Pandas 3.0 премина на PyArrow за низови колони, Polars остава значително по-бърз при group-by, joins и агрегации над 100K реда. На бенчмарк с 240M реда Polars дава ~10× ускорение при group-by и до 11× при sort и filter.
Кога да използвам Polars вместо Pandas?
Изберете Polars за нови ETL пайплайни, аналитични заявки над 100K реда, планирани job-ове и данни, които не се събират в паметта. Задръжте Pandas за бърза експлорация в Jupyter и когато интегрирате с библиотеки, които не разбират Arrow (например някои по-стари ML инструменти).
Мога ли да ползвам Polars със scikit-learn?
Да. Използвайте Polars за предварителна обработка и извикайте .to_pandas() или .to_numpy() точно преди fit(). Тези конверсии са zero-copy за числови колони, така че overhead-ът е минимален.
Как да включа streaming engine в Polars?
Извикайте .collect(engine="streaming") върху LazyFrame заявка, или задайте глобално pl.Config.set_engine_affinity("streaming"). От Polars 1.39 streaming поддържа merge join и AsOf join, така че покрива повечето реални pipeline-и.
Поддържа ли Polars GPU?
Да, чрез експерименталния NVIDIA cuDF backend, който активирате с collect(engine="gpu"). Той е най-полезен за големи group-by и joins над числови колони. За IO-heavy pipeline-и с текст CPU streaming engine обикновено е по-бърз.
Практическо ръководство за Optuna 4.x в Python: TPE и GP samplers, pruning, multi-objective оптимизация и работещи примери със Scikit-learn и XGBoost за 2026 г.
Научете как да създавате ефективни признаци за ML модели с Pandas 3.0 и Scikit-learn. Практическо ръководство с код за кодиране, скалиране, TargetEncoder, ColumnTransformer и селекция на признаци.
Научете как да провеждате t-тестове, ANOVA, хи-квадрат и регресия в Python със SciPy и Statsmodels — практическо ръководство с работещи примери и визуализации за 2026 г.