首页
/ Polars Python(py-polars):从安装、查询执行到引擎选型,全面解析 Python 侧 DataFrame 查询引擎

Polars Python(py-polars):从安装、查询执行到引擎选型,全面解析 Python 侧 DataFrame 查询引擎

2026-09-05 21:14:57作者:江焘钦

本文以 py-polars/README.md 为主线,系统讲解 Polars 的 Python 绑定 py-polars:如何安装(含可选依赖与运行时包)、如何用惰性表达式组合查询、collect()engine 参数如何选择 in-memory / streaming / gpu 三种执行引擎,以及如何从源码编译出针对本机 CPU 优化的本地构建。读完后你可以独立完成 py-polars 的安装配置、写出可并行执行的惰性查询,并针对超出内存(larger-than-RAM)的数据集选对执行引擎。

py-polars 是什么:Rust 内核之上的 Python 查询引擎

py-polars 是 Polars 的 Python 绑定。Polars 本身是一个用 Rust 编写的 DataFrame 分析型查询引擎,官方定位是"fast, easy to use and expressive"(快速、易用、表达力强)。按照 README 的总结,其核心能力包括:

  • Fast:用 Rust 从头实现,多线程 + 向量化(SIMD)执行;
  • Lazy & eager execution:同时支持惰性求值和立即执行,惰性查询自带查询优化;
  • Larger-than-RAM:流式引擎可处理超出内存的数据集;
  • Expressive API:用表达式(expression)组合复杂查询;
  • Extensible:可通过 I/O 插件与表达式插件用自定义代码扩展;
  • Multi-language:同一套 Rust 内核提供 Python、Rust、Node.js、R 与 SQL 绑定;
  • GPU support:可选地在 NVIDIA GPU 上加速查询;
  • Interoperable:基于 Apache Arrow 列式格式,实现零拷贝的数据共享。

从仓库结构看,py-polars/src/polars/ 下的 Python 代码是一层薄薄的 API 封装,真正的计算发生在 PyO3 绑定的 Rust crate polars-python 中,最终通过运行时包(runtime)以 cdylib 形式交付给 Python 解释器加载。这一分层结构直接决定了后面的安装方式与编译方式。

惰性查询实战:表达式组合 + 并行执行

README 给出的核心示例展示了 Polars 的基本编程范式——查询由表达式组合而成,惰性(lazy)查询会自动被优化,并在所有可用核心上并行执行:

import polars as pl

df = (
    pl.scan_parquet("orders.parquet")
    .filter(pl.col("status") == "shipped")
    .group_by("customer_id")
    .agg(
        pl.col("amount").sum().alias("total"),
        pl.len().alias("n_orders"),
    )
    .sort("total", descending=True)
    .collect()
)

要点拆解:

  1. pl.scan_parquet(...) 从 Parquet 文件直接扫描,得到 LazyFrame;仓库的 examples/datasets/pds_heads/ 目录中附带了 TPC-H 数据集的头部样本(customer.featherorders.featherlineitem.feather 等),可用于本地复现类似查询;
  2. .filter() / .group_by() / .agg() / .sort() 每一步都只是对查询计划(query plan)的追加,不会立即计算;
  3. pl.col("amount").sum()pl.len() 等表达式在聚合中通过 .alias() 重命名输出列;
  4. 链尾的 .collect() 才是触发优化的物化点——惰性查询在此被优化后并行执行,返回 DataFrame

collect() 的 engine 参数:三种执行引擎的源码级选型

README 中提到流式执行可用 collect(engine='streaming') 触发。当前仓库中 collect() 的完整签名与文档字符串位于 py-polars/src/polars/lazyframe/frame.py,从中可以确认 engine 的全部取值与行为:

engine 取值 行为
"auto"(默认) 使用 Config.set_engine_affinity 或环境变量 POLARS_ENGINE_AFFINITY 设置的引擎,否则回退为流式引擎
"in-memory" 内存引擎,默认引擎,适合能整体放入内存的数据集
"streaming" 流式引擎,按批次(batch)处理查询,降低内存压力,官方注明"很快将成为 Polars 的默认引擎"
"gpu" CUDA GPU 引擎,需要 NVIDIA GPU 与 cudf-polars;可传 pl.GPUEngine(device=1) 在多卡环境中精细选择设备

几个源码层面的细节值得注意:

  • 引擎类型别名定义在 py-polars/src/polars/_typing.pyEngineTypeName = Literal["auto", "in-memory", "streaming", "gpu"]EngineType 允许传字符串或 Engine 实例;
  • 当所选引擎无法运行某条查询时,Polars 会回退到内存引擎;GPU 模式被明确标注为不稳定(unstable),并非所有查询都能在 GPU 上成功执行,但应透明回退到默认引擎,设置 POLARS_VERBOSE=1 可查看回退原因;
  • 2.0 版本移除了旧的 streaming=True 布尔参数(源码中通过 @removed_parameters 声明其于 2.0 移除),现在统一使用 engine="streaming"
  • collect() 还支持 background=True 在后台运行查询并返回可查询、可取消的句柄,同样被标注为不稳定 API;optimizations 参数可控制查询优化开关。

流式引擎在测试体系中有一等公民地位:py-polars/Makefile 中的 test-streaming 目标通过设置 POLARS_AUTO_STREAMING=1 环境变量让全部单测默认走流式引擎执行,说明流式路径是与内存路径同等维护的核心能力。

Larger-than-RAM:用流式引擎处理超内存数据集

README 明确指出:如果数据装不进内存,Polars 的查询引擎可以流式处理查询(或查询的一部分),大幅降低内存需求——例如"可能让你在笔记本上处理 250GB 的数据集"。触发方式就是:

lf.collect(engine="streaming")

与之相关的调优配置还包括 polars.Config.set_streaming_chunk_size(设置流式批次大小,见 collect() 的 See Also 段)。从 py-polars/Makefiletest-streaming 目标可以看到,仓库自身就用 POLARS_AUTO_STREAMING=1 环境变量做整条流水线的全流式回归验证,这意味着在流式模式下运行过的操作都经过了与内存模式相当的测试覆盖。

安装 py-polars:pip 安装、运行时包与可选依赖

最简安装

pip install polars

当前仓库 py-polars/pyproject.toml 中可以看到 Python 包的完整安装事实(适用于当前仓库版本):

  • 包名为 polars,版本 2.0.0rc1,要求 requires-python >= 3.10,分类器覆盖 Python 3.10–3.13;
  • 核心依赖是运行时包 polars-runtime-32 == 2.0.0rc1,可选还有 rt64polars-runtime-64)与 rtcompatpolars-runtime-compat)两个额外运行时变体。从 py-polars/runtime/ 目录结构看,这些运行时 crate 由 py-polars/runtime/template.py 从模板生成(py-polars/runtime/README.md 明确提示"只编辑 template,改完运行 template.py");其中 polars-runtime-32 的 Rust crate 名为 polars-runtime-32,但编译产物库名为 _polars_runtime(见 py-polars/runtime/polars-runtime-32/Cargo.toml),即"32 位索引/常规版、64 位索引版、Rosetta 兼容版"对应不同底层运行时包;
  • 可选依赖按场景分组(安装时用 pip install polars[组名]):
场景 extras 组 依赖
Excel calamine / openpyxl / xlsx2csv / xlsxwriter,聚合为 excel fastexcel、openpyxl、xlsx2csv、xlsxwriter
数据库 adbc / connectorx / sqlalchemy,聚合为 database ADBC 驱动、connectorx、SQLAlchemy
互操作 numpy / pandas / pyarrow / pydantic numpy ≥1.16、pandas、pyarrow ≥7、pydantic
湖表格式 deltalake / iceberg Delta Lake ≥1.0、pyiceberg ≥0.9
云存储 fsspec fsspec
异步 async gevent
可视化 plot / graph / style altair ≥5.4、matplotlib、great-tables
GPU 引擎 gpu cudf-polars-cu12
全量 all 以上 I/O、数据库、互操作等组合(不含 gpu)

高级安装场景

README 提示,在以下场景应查阅安装指南选择特殊构建:

  • 预期数据行数超过 2^32(约 42 亿行)——需要 64 位索引运行时;
  • 运行在较老的 CPU 上(例如 2011 年之前);
  • 在 Apple Silicon 上运行 x86-64 构建的 Python(Rosetta)。

这与上文 polars-runtime-32 / polars-runtime-64 / polars-runtime-compat 三个运行时变体的划分一一对应。

从源码编译:maturin + make 构建矩阵

需要"bleeding edge"版本,或希望针对本机 CPU 架构做极致优化时,可以自行编译。README 给出的步骤为:

  1. 安装 Rust 编译器;
  2. 安装 maturin:pip install maturin
  3. 进入 py-polars 目录后执行其中一个构建目标:
构建命令 特性
make build 慢速二进制,带调试断言、有限符号,编译快(开发用)
make build-debug 同 build,但保留完整符号,二进制较大
make build-release 快速二进制,无调试断言、最小调试符号,编译时间长
make build-nodebug-release 同 release 但完全无调试符号,编译略快
make build-debug-release 同 release 但带完整调试符号,编译略慢
make build-dist-release 最快二进制,极端编译时间(分发用)

这些目标在 py-polars/Makefile 中逐一存在,并统一委托根目录 Makefile 执行实际编译。

LTS_CPU 参数:默认按现代 CPU 开启优化;如果你的 CPU 较老(不支持 AVX2 等指令集),需以 LTS_CPU=1 编译。根 Makefile 中的实现印证了这一点:LTS_CPU 只接受 0/1(否则报错),amd64 架构下——

  • LTS_CPU=1 时 RUSTFLAGS 仅启用 sse3/ssse3/sse4.1/sse4.2/popcnt/cmpxchg16b
  • 默认(现代 CPU)时额外启用 avx/avx2/fma/bmi1/bmi2/lzcnt/pclmulqdq/movbe-Z tune-cpu=skylake

这解释了为什么 README 强调老 CPU 用户必须显式设置 LTS_CPU=1,否则产物可能包含机器无法执行的 AVX2 指令。

crate 命名说明:README 特别指出,实现 Python 绑定的 Rust crate 叫 py-polars(本仓库 crates/polars-python 对应其编译入口),以区别于被包装的 Rust crate polars 本身;但 Python 包与模块都叫 polars,所以依然可以 pip install polars + import polars

生态延伸:贡献、分布式与许可

  • 贡献:README 指引贡献者阅读贡献指南并关注 issue tracker 中的 accepted issues,新手可先认领 good first issue 标签熟悉项目;仓库根目录的 CONTRIBUTING.md 是这些流程的落地文档;
  • 分布式 Polars:单机硬件不足时,可以按官方文档将查询横向扩展到集群上执行(Distributed Polars / polars-cloud 方向);
  • 许可:Polars 采用 MIT License(SPDX: MIT),见 LICENSE

小结

py-polars 把"Rust 内核 + Python 易用性"结合得很紧:pip install polars 即可获得默认运行时包与全功能内核;惰性查询经 collect() 自动优化并并行执行;engine 参数是内存、超内存、GPU 三种执行路径的统一入口,且不支持的操作会透明回退到内存引擎;源码编译则通过 make build-* 六档目标与 LTS_CPU 开关覆盖从日常开发到分发发布、从现代 CPU 到 2011 年前老 CPU 的完整场景。关键实现可继续从 py-polars/src/polars/lazyframe/frame.pypy-polars/pyproject.tomlMakefile 深入阅读。

登录后查看全文
热门项目推荐
相关项目推荐