Polars中read、scan与sink方法的区别是什么?
Polars中read、scan、sink三类输入方法的区别
1. read_* 系列(比如read_csv、read_parquet)
- 本质就是把整个数据集一次性塞进内存,返回现成的
DataFrame。 - 拿到
DataFrame后就能直接做各种操作,所有计算都是立刻执行的,没什么弯弯绕。 - 适合数据量不大、内存装得下,而且你需要反复对全量数据做交互式操作的场景。
- 示例代码:
import polars as pl df = pl.read_csv("data.csv") # 马上就出结果 filtered_df = df.filter(pl.col("age") > 30)
2. scan_* 系列(比如scan_csv、scan_parquet)
- 它根本不加载数据,只是帮你写好一套“读取+处理”的操作计划,返回
LazyFrame。 - 你后续加的过滤、选择列这些操作,都只是在给这个计划加步骤,直到你调用
collect(),它才会实际跑起来,而且Polars会自动优化这个计划(比如只读需要的列、提前过滤数据),省时间省资源。 - 适合数据量远大于内存,或者你要写一堆复杂操作,想让Polars帮你优化执行逻辑的场景。
- 示例代码:
import polars as pl lf = pl.scan_csv("large_data.csv") # 这一步只是记下来要做什么,没实际干活 filtered_lf = lf.filter(pl.col("age") > 30).select("name", "age") # 现在才真的读取数据、执行过滤,返回结果 result_df = filtered_lf.collect()
3. sink_* 系列(比如sink_csv、sink_parquet)
- 这是流式处理玩法:边读数据、边处理、边直接写到输出文件里,全程不会把整个数据集或者中间结果存在内存里。
- 处理完就直接输出,内存里只留当前正在处理的一小批数据,资源占用极低。
- 适合要处理超大数据集,而且最终目的就是把处理结果存成文件,不需要把全量数据留在内存里的场景。
- 示例代码:
import polars as pl # 从源文件读一点、过滤一点、写一点,全程不占大内存 pl.scan_csv("huge_data.csv") \ .filter(pl.col("age") > 30) \ .sink_csv("filtered_huge_data.csv")
一张表看懂核心差异
| 对比维度 | read_* | scan_* | sink_* |
|---|---|---|---|
| 数据加载时机 | 立刻把全量数据塞进内存 | 先不加载,只存操作计划 | 逐批读数据,不存全量 |
| 返回结果 | DataFrame(可直接用) | LazyFrame(需collect) | 无返回值(直接写文件) |
| 内存占用情况 | 高(要装下整个数据集) | 极低(只存操作逻辑) | 极低(仅存当前批次) |
| 最佳适用场景 | 小数据集、交互式操作 | 大数据集、复杂查询优化 | 超大数据集、直接输出结果 |
内容的提问来源于stack exchange,提问作者Talha Tayyab
相关产品推荐
相关产品推荐

