Polars Python(py-polars):从安装、查询执行到引擎选型,全面解析 Python 侧 DataFrame 查询引擎
本文以 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()
)
要点拆解:
pl.scan_parquet(...)从 Parquet 文件直接扫描,得到LazyFrame;仓库的examples/datasets/pds_heads/目录中附带了 TPC-H 数据集的头部样本(customer.feather、orders.feather、lineitem.feather等),可用于本地复现类似查询;.filter()/.group_by()/.agg()/.sort()每一步都只是对查询计划(query plan)的追加,不会立即计算;pl.col("amount").sum()、pl.len()等表达式在聚合中通过.alias()重命名输出列;- 链尾的
.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.py:
EngineTypeName = 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/Makefile 的 test-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,可选还有rt64(polars-runtime-64)与rtcompat(polars-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 给出的步骤为:
- 安装 Rust 编译器;
- 安装 maturin:
pip install maturin; - 进入
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.py、py-polars/pyproject.toml 与 Makefile 深入阅读。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00