polars vs pandas(2026 视角)

起因

pandas 是 Python 数据界 15 年的事实标准。但:

  • 单线程(GIL),大数据慢
  • 内存膨胀(同一列多份 copy)
  • API 设计累赘(SettingWithCopyWarning、index 烦)

polars 是 Rust 写的 DataFrame,2020+ 起飞。Apache Arrow 内存格式 +
多线程 + lazy 执行。
2026 视角看,polars 在多个维度全面超越 pandas。

pip install polars
# 或者 uv add polars

句法对比

import polars as pl
import pandas as pd

# pandas
df = pd.read_csv('orders.csv')
result = (
    df[df['country'] == 'US']
    .groupby('product')
    .agg({'amount': 'sum', 'qty': 'count'})
    .reset_index()
    .sort_values('amount', ascending=False)
    .head(10)
)

# polars
df = pl.read_csv('orders.csv')
result = (
    df.filter(pl.col('country') == 'US')
    .group_by('product')
    .agg([
        pl.col('amount').sum(),
        pl.col('qty').count(),
    ])
    .sort('amount', descending=True)
    .head(10)
)

polars 句法 method chain 顺。
明确的 pl.col(...) 比 pandas df['x'] 在复杂 expression 里清晰。

性能

我们一个 10 GB CSV / 80 列:

操作 pandas polars polars-lazy
read_csv 95s 22s 22s
filter + groupby + agg 38s 5s 3s
join 两 10 GB 90s (OOM 风险) 18s 12s
sort by 3 列 25s 4s 3s

5-10x 快。32 核机器更明显(pandas 单核)。

内存:pandas 30 GB peak,polars 12 GB peak(Arrow columnar + zero-copy)。

lazy 执行

polars 杀手 feature:

# eager(每步实际跑)
df = pl.read_csv('big.csv')
result = df.filter(...).group_by(...).agg(...)

# lazy(构建 query plan,scan 时才执行)
result = (
    pl.scan_csv('big.csv')      # 注意 scan_ 而不是 read_
    .filter(pl.col('x') > 0)
    .group_by('y')
    .agg(pl.col('z').sum())
    .collect()                   # 触发执行
)

lazy 优势:

  • predicate pushdown:filter 推到 CSV 读取阶段,只读符合行
  • projection pushdown:只读用到的列
  • CSE:重复 expression 算一次
  • streaming:> 内存数据流式处理
result = (
    pl.scan_csv('100GB.csv')
    .filter(pl.col('date') > '2025-01-01')
    .select(['user_id', 'amount'])     # 只读这俩列
    .group_by('user_id')
    .agg(pl.col('amount').sum())
    .collect(streaming=True)             # 流式,不全加载
)

100 GB CSV 在 16 GB 机器跑得动。pandas 没 streaming 直接 OOM。

SQL interface

ctx = pl.SQLContext()
ctx.register('orders', df)
result = ctx.execute("""
    SELECT country, SUM(amount)
    FROM orders
    WHERE qty > 5
    GROUP BY country
""").collect()

熟 SQL 但不熟 polars expression → 写 SQL。

跟 pandas 互转

df_pd = pl.DataFrame(...).to_pandas()
df_pl = pl.from_pandas(df_pd)

零拷贝(用 Arrow buffer 共享)。混用方便。

与 pandas 2.x(Arrow backend)对比

pandas 2.x 加了 pyarrow backend:

df = pd.read_csv('data.csv', dtype_backend='pyarrow')

性能改善但仍单线程
比 polars 还差一截(polars 多核 + lazy + native rust)。

与 spark / dask 对比

pandas polars dask spark
内存模型 row columnar (Arrow) partition columnar
并行 单线程 多线程 多进程/集群 集群
数据规模 < RAM > RAM (streaming) TB PB
学习曲线
启动 0.1s 0.1s 1s 30s+
  • < 10 GB → polars
  • 10 GB - 1 TB → polars streaming / dask
  • 1 TB → spark / dask 集群

实际项目迁移

我们 ETL pipeline 30 个 script,pandas → polars:

1. read_csv → scan_csv:1 行换
2. df[df.x > 5] → df.filter(pl.col('x') > 5):手动改
3. groupby().agg({}) → group_by().agg([]):手动改
4. .reset_index() → 删(polars 无 index 概念)
5. lambda apply → 改成 polars expression

大约 30 - 50% 行需要改。但跑速从 2 小时 → 12 分钟,值得。

LLM 辅助迁移很方便,pandas 到 polars 是 well-defined 转换。

API 缺点 / 注意

  • 没 index(这是 feature 不是 bug,但 pandas 老用户要适应)
  • merge → join(语义稍不同,pandas merge 默认 inner,polars join 默认 inner,OK)
  • pivot / melt 等也有 + 语义略不同
  • 没 multi-index column

90% workflow polars OK。某些特殊 transformation(时间序列 resample 加
multi-index)pandas 仍胜。

用什么场景

  • 新 ETL → polars 默认
  • 现有 pandas codebase → 看痛点决定,不必全迁
  • notebook 探索性分析 → 二选一都行,polars 性能优势更大
  • DataFrame for ML 输入 → sklearn 仍 pandas 友好;polars 转 numpy
    传 sklearn

我的工作流

  • 数据 ingestion / heavy ETL:polars
  • ML feature engineering:polars
  • 给 sklearn / pytorch 时:.to_numpy().to_pandas()
  • 临时小数据:pandas(生态广)

踩过的坑

  1. expression 错位pl.col('x') + 5 - pl.col('y') vs
    pl.col('x') + (5 - pl.col('y'))。运算符优先级跟 Python 一致,
    但容易看走眼。

  2. lazy collect 慢:忘了 .collect() 一直 lazy。debug 时
    .head(10).collect() 看数据。

  3. datetime 时区:polars 严格 timezone aware / naive 区分。
    pandas 经常混。从 pandas 来的 dataframe pl.from_pandas
    timezone 信息可能丢。

  4. null 处理:polars 用 Arrow null bit,跟 pandas NaN 不同。
    pl.col('x').is_null() 不是 x != x

  5. groupby 后默认按 key 排序:pandas 默认排,polars 默认不排。
    要 sort 显式 .sort()

精确评价 共 0 人评价
可复现性
可复现 · 0 不可复现 · 0
文风
文风流畅 · 0 文风晦涩 · 0
立场
支持 · 0 反对 · 0

登录后即可对本帖作出评价。

评论区 0 条 · 所有人可在此交流

登录后参与评论。

还没有评论,来说两句。