本文目录导读:

是的,Polars 支持延迟计算(Lazy Evaluation),并且这是 Polars 的核心优势之一。
它通过 LazyFrame(惰性 DataFrame)来实现,你可以先构建一个查询计划,直到你显式调用 .collect() 方法时,Polars 才会真正执行计算。
核心概念:Eager vs Lazy
- Eager(即时模式):普通的 DataFrame 操作(如
df.filter()、df.with_columns())会立即执行并返回结果,每次操作都要遍历数据,性能较差,且无法进行全局优化。 - Lazy(惰性模式):通过
.lazy()方法将 DataFrame 转换为LazyFrame,之后的所有操作(filter、select、join等)都只是“记录”下来,形成一个查询计划,只有在调用.collect()时,Polars 才会对整个查询计划进行优化(如谓词下推、投影下推、消除冗余计算等),然后一次性高效执行。
如何使用延迟计算
import polars as pl
# 1. 创建普通 DataFrame (Eager)
df = pl.DataFrame({
"name": ["Alice", "Bob", "Charlie"],
"age": [25, 30, 35],
"score": [85, 90, 95]
})
# 2. 转换为 LazyFrame (惰性)
lazy_df = df.lazy() # 或者 pl.scan_csv("file.csv") 直接读取为 LazyFrame
# 3. 构建查询计划(此时并没有实际计算)
query = (lazy_df
.filter(pl.col("age") > 28)
.select(["name", "score"])
.with_columns((pl.col("score") * 1.1).alias("adjusted_score"))
)
# 4. 执行计算 (触发优化和实际计算)
result = query.collect()
print(result)
# shape: (2, 3)
# ┌─────────┬───────┬─────────────────┐
# │ name ┆ score ┆ adjusted_score │
# │ --- ┆ --- ┆ --- │
# │ str ┆ i64 ┆ f64 │
# ╞═════════╪═══════╪═════════════════╡
# │ Bob ┆ 90 ┆ 99.0 │
# │ Charlie ┆ 95 ┆ 104.5 │
# └─────────┴───────┴─────────────────┘
关键点:
lazy_df.filter()不会立即执行,它只是返回一个新的LazyFrame。- 所有惰性操作都链接在一起,直到
.collect()才触发计算。
延迟计算的核心优势
- 查询优化(Query Optimization)
Polars 的优化器会自动应用以下优化:
- 谓词下推:将过滤条件尽可能地推后执行(例如在读取数据时就过滤掉不必要的行)。
- 投影下推:只读取需要的列,减少内存占用和 I/O。
- 爆炸消除:避免不必要的中间结果展开。
- 重排操作:以更高效的顺序执行操作(如先过滤后 join,而不是先 join 后过滤)。
- 内存效率 延迟执行允许 Polars 以流式或批处理方式处理数据,避免生成多个中间副本,这对于处理大型数据集(甚至超过内存大小的数据集)至关重要。
- 多核并行 延迟计算允许 Polars 在优化后的查询计划中更好地利用所有 CPU 核心,实现自动并行化(例如将过滤和聚合分配到不同的线程)。
- 流式查询(Streaming)
对于超大数据集(如 100GB 的 CSV 文件),你可以使用
.collect(streaming=True),Polars 会以流式方式处理数据,一次只加载一小块数据,而不是将整个数据集加载到内存中。
何时使用延迟计算?
| 场景 | 推荐使用 Lazy? | 原因 |
|---|---|---|
| 小型数据集 (< 1GB) | 可选,非必须 | Eager API 足够快,且代码更直观,Lazy 的优势不明显。 |
| 大型数据集 (> 1GB) 或复杂操作 | 强烈推荐 | 延迟计算能大幅减少内存使用和运行时间,特别是涉及多步过滤、聚合、Join时。 |
| 流式处理超大文件 | 必须 | 使用 pl.scan_csv() 结合 .collect(streaming=True) 处理无法装入内存的数据。 |
| 链式多步数据处理 | 推荐 | 延迟计算能在链条尾部一次性优化整个流程,避免中间结果多次缓存。 |
如何切换到延迟模式?
- 从文件读取:直接使用
pl.scan_csv()、pl.scan_parquet()、pl.scan_ndjson()等函数,它们默认返回 LazyFrame。 - 从已有 DataFrame:使用
df.lazy()转换。 - 从 LazyFrame 回到 Eager:使用
.collect()。
Polars 不仅支持延迟计算,而且它的设计哲学就是鼓励你使用延迟计算,对于任何非 trivial 的数据处理任务,尤其是数据量大或操作复杂时,使用 Lazy API 是获得高性能和高内存效率的关键,如果你之前习惯使用 Pandas(纯 Eager),切换到 Polars 后,建议优先思考能否用 Lazy API 实现,以充分利用其优化能力。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播