- 数据分析
- 大数据
【免费下载链接】polars
Extremely fast Query Engine for DataFrames, written in Rust
DataFrame是 Polars 最核心的二维表格数据结构。本文以仓库内 Python API 参考索引页 py-polars/docs/source/reference/dataframe/index.rst 为主线,结合其下 11 个分类页面(聚合、属性、计算、描述性统计、导出、分组、修改/选择、杂项、绘图、样式等)与源码实现 py-polars/src/polars/dataframe/frame.py(约 1.3 万行),系统梳理全部公开方法。读完本文,你将掌握 DataFrame 的完整方法地图、各方法的关键参数与典型用法,并能直接在交互式分析或生产脚本中按图索骥。
文档索引:一份可导航的 DataFrame API 地图
index.rst是 Sphinx 文档体系中的 API 参考入口页。它用toctree指令聚合了 11 个子页面:
.. toctree:: :maxdepth: 2 :hidden: aggregation attributes computation descriptive export group_by modify_select miscellaneous plot style随后通过autoclass+:members:指令自动生成DataFrame类的完整成员文档。这种"索引页 + 分类子页"的结构,意味着 Polars 的 DataFrame API 被清晰地划分为十个功能域:聚合、属性、计算、描述性统计、导出、分组、修改/选择、杂项、绘图、样式。以下按此分类逐一展开,并在每个分类给出对应子页面(如 aggregation.rst)的完整方法清单与源码佐证。
属性(Attributes):快速读取框架的元信息
对应子页面 attributes.rst,共 7 个只读属性,在 frame.py 中实现:
| 属性 | 返回类型 | 说明 |
|---|---|---|
columns | list[str] | 列名列表,也支持 setter 批量改名 |
dtypes | list[DataType] | 各列的数据类型(如Int64、Float64、String) |
flags | dict[str, dict[str, bool]] | 每列的优化标志,如是否已排序(SORTED)、快速探索标志 |
height | int | 行数 |
schema | Schema | 有序的 {列名: 数据类型} 映射,Polars 的 Schema 类型定义见 py-polars/src/polars/schema.py |
shape | tuple[int, int] | (行数, 列数) |
width | int | 列数 |
import polars as pl df = pl.DataFrame({"a": [1, 2], "b": [3.0, 4.0]}) df.shape # (2, 2) df.height # 2 df.width # 2 df.columns # ['a', 'b'] df.dtypes # [Int64, Float64] df.schema # Schema({'a': Int64, 'b': Float64}) df.flags # 例如 {'a': {'SORTED': False, ...}}值得注意:columns同时具备 setter 能力(df.columns = ["x", "y"]),这是快速批量重命名的方式;而细粒度重命名应使用rename方法(见"修改/选择"分类)。
聚合(Aggregation):列级统计的快捷入口
对应子页面 aggregation.rst,提供 13 个对整个 DataFrame 所有数值列生效的聚合方法:
- 单值统计:
count、max、mean、median、min、product、quantile、std、sum、var - 水平(跨行)聚合:
max_horizontal、mean_horizontal、min_horizontal、sum_horizontal(文档清单中水平聚合有 4 个,实际完整清单含max_horizontal/mean_horizontal/min_horizontal/sum_horizontal)
典型用法:
df = pl.DataFrame({"a": [1, 2, 3], "b": [4.0, 5.0, 6.0]}) df.sum() # 各列求和:a=6, b=15.0 df.mean() # 各列均值 df.quantile(0.9) # 各列 90% 分位数,interpolation 参数可选 df.sum_horizontal() # 逐行对 a、b 求和,返回新 Seriesquantile的interpolation参数支持nearest、higher、lower、midpoint、linear、equiprobable六种方式(与describe共用同一QuantileMethod类型,定义于 py-polars/src/polars/_typing.py)。这些方法内部会先转成惰性表达式再执行,底层由 Rust 内核的Series聚合算子完成。
计算(Computation):函数式折叠与哈希
对应子页面 computation.rst,仅两个方法:
fold(operation, columns):沿列方向做函数式折叠,可将多列归约为单个 Series,例如df.fold(lambda acc, s: acc + s)等价于逐行水平求和;hash_rows(seed=0, seed_1=0, seed_2=0, seed_3=0):对每一行计算哈希值,返回UInt64类型的 Series。多 seed 设计用于需要多路独立哈希的场景(如分布式分片、随机打散)。行哈希常用于去重、分组键构造与分桶,其底层实现在 Rust 侧的 hashing 模块(crates/polars-core/src/hashing)。
描述性统计(Descriptive):一眼看懂数据概况
对应子页面 descriptive.rst,包含 10 个方法:
| 方法 | 用途 |
|---|---|
describe | 生成分位数、均值、标准差等汇总统计表 |
estimated_size | 估算内存占用(可按SizeUnit指定单位) |
glimpse | 类似 R 中glimpse的紧凑预览,逐列显示类型与样例值 |
is_duplicated | 标记重复行(布尔 Series) |
is_empty | 是否 0 行 |
is_sorted | 检查各列是否已排序(reverse参数控制升降序) |
is_unique | 标记唯一行 |
n_chunks | 列的分块(chunk)数量,Polars 列式存储按 chunk 组织 |
n_unique | 各列去重后的不同值数量 |
null_count | 各列空值数量 |
show | 控制台打印表格(截断显示) |
describe是其中使用频率最高的方法,源码在 frame.py:
df.describe() # 默认输出 count/null_count/mean/std/min/25%/50%/75%/max 共 9 行统计关键参数:
percentiles:默认(0.25, 0.50, 0.75),可传入自定义分位数序列(取值必须在[0, 1]区间),中位数默认以 50% 分位出现;interpolation:分位数插值方式,默认nearest,可选linear等。
with pl.Config(tbl_rows=12): df.describe(percentiles=[0.1, 0.3, 0.5, 0.7, 0.9], interpolation="linear")注意官方文档明确警告:describe的输出不保证跨版本稳定,适合交互式探索而非程序化依赖。describe内部实现是self.lazy().describe(...),即委托给 LazyFrame 的分位数与统计逻辑。
导出(Export):与生态互操作的核心通道
对应子页面 export.rst,覆盖 Python 生态互操作的几乎所有出口。完整清单:
__array__:支持np.asarray(df)的协议钩子;__arrow_c_stream__:实现 Python 社区标准的 Arrow C Stream 协议(PEP 734),零拷贝暴露底层 Arrow 数据;to_arrow:转为 PyArrowTable(支持compat_level兼容级别参数);to_dict/to_dicts:转为{列名: 值列表}字典,或逐行字典列表;to_init_repr:生成可重新构造该 DataFrame 的代码字符串(即repr重建表达式);to_jax:导出到 JAX 数组(需安装 jax);to_numpy:转为 NumPyndarray(to_numpy(*, allow_copy, writable, zero_copy_only)支持零拷贝导出,见 frame.py);to_pandas:转为 pandasDataFrame(to_pandas(*, dtype_backend, engine, maintain_order, ...),见 frame.py);to_struct:将整张表压缩为一个Struct类型的 Series;to_torch:导出为 PyTorchTensor(需安装 torch)。
df.to_numpy() # → ndarray df.to_pandas() # → pandas.DataFrame df.to_arrow() # → pyarrow.Table df.to_dict() # → {'a': [1, 2], 'b': [3.0, 4.0]} df.to_struct() # → Series 结构类型这些导出的互操作依赖检查集中在 py-polars/src/polars/_dependencies.py,未安装对应库时会抛出带安装指引的ModuleUpgradeRequiredError。核心转换逻辑由 Rust 侧 PyO3 绑定实现,入口见 crates/polars-python/src/dataframe/export.rs。
分组(GroupBy):最强大的变换引擎
对应子页面 group_by.rst。调用df.group_by(...)后返回GroupBy对象(定义于 py-polars/src/polars/dataframe/group_by.py),文档列出 17 个方法:
- 聚合类:
agg、all、first、last、len、max、mean、median、min、n_unique、quantile、sum - 子集选择类:
head、tail - 条件过滤类:
having - 自定义映射:
map_groups - 迭代:
__iter__
group_by方法签名(frame.py):
df.group_by(*by, maintain_order=False, **named_by) -> GroupBy*by:分组键,接受列名字符串、表达式或选择器;maintain_order=True:保证分组顺序与输入一致,但会牺牲性能,且会阻断流式引擎(streaming engine)执行;**named_by:以关键字参数形式传入额外分组列并重命名。
df = pl.DataFrame({ "a": ["a", "b", "a", "b", "c"], "b": [1, 2, 1, 3, 3], "c": [5, 4, 3, 2, 1], }) df.group_by("a").agg(pl.col("b").sum()) df.group_by("a", maintain_order=True).agg(pl.col("c")) # 组内聚合为 list df.group_by(["a", "b"]).agg(pl.max("c")) df.group_by("a", pl.col("b") // 2).agg(pl.col("c").mean()) # 支持表达式键GroupBy对象本身可迭代,每次返回(组名元组, 组内 DataFrame),迭代状态由 group_by.py 中的GroupByIter管理:
for name, data in df.group_by("a"): print(name) # ('a',) 形式的元组 print(data) # 该组的 DataFramehaving提供分组后的行过滤语义(等价于 SQLHAVING);map_groups允许用 Python 函数对每个分组做自定义处理(*args为各组的 Series,返回Series或DataFrame)。除GroupBy外,group_by.py 还定义了DynamicGroupBy(动态/时间窗分组)与RollingGroupBy(滚动窗口分组),分别由df.group_by_dynamic(...)与df.rolling(...)返回。
修改/选择(Modify/Select):日常操作的主战场
对应子页面 modify_select.rst,这是规模最大的一类,共 72 个方法,覆盖选择、过滤、排序、连接、变形、填充等全部日常操作。按用途可进一步细分:
选择与切片:select、select_seq、__getitem__(df[...]索引)、head、tail、limit、slice、gather、gather_every、row、rows、rows_by_key、item、get_column、get_column_index、get_columns、iter_columns、iter_rows、iter_slices
df.head(5) # 前 5 行 df.tail(5) # 后 5 行 df.select("a", "b") # 按表达式选择列 df["a"] # 取列(Series) df[0] # 取行 df.gather([0, 2]) # 按行索引取行 df.rows() # 逐行元组 df.row(0, named=True) # 命名行过滤与去空:filter、drop_nulls、drop_nans、fill_null、fill_nan、drop、remove
df.filter(pl.col("a") > 1) df.drop_nulls(subset=["a"]) # 仅检查指定列 df.fill_null(0) # 或 fill_null(strategy="forward") df.drop("b") # 删除列排序与极值:sort、top_k、bottom_k、set_sorted、reverse
df.sort("a", descending=True, nulls_last=True) df.top_k(3, by="a") # 按列 a 取前 3 大行列操作:with_columns、with_columns_seq、rename、cast、replace_column、insert_column、remove、hstack、vstack、extend、clear、clone、rechunk、shrink_to_fit、to_series、to_dummies、with_row_index、match_to_schema
df.with_columns((pl.col("a") * 2).alias("a2")) df.rename({"a": "x"}) # 或 rename 接收映射 df.cast({"a": pl.Float32}) df.with_row_index("idx") # 添加行号列 df.to_series(0) # 取第 0 列为 Series df.vstack(other) # 纵向堆叠(返回新帧) df.extend(other) # 原地追加(返回 None,in-place 语义) df.rechunk() # 合并列的分块变形:explode、transpose、pivot、unpivot、unstack、unnest、partition_by
df.explode("list_col") # 展开 List 列 df.pivot(on="k", index="id", values="v") # 宽表 df.unpivot(on=["a", "b"], index="id") # 长表 df.transpose(include_header=True) df.partition_by("a") # 按列值切分为多个 DataFrame连接(Join):join、join_asof、join_where、merge_sorted、update。其中join是使用率最高的方法,签名与参数详解见 frame.py:
df.join(other, on="ham") # 默认 inner df.join(other, on="ham", how="full") # left/right/full/semi/anti/cross df.join(other, how="cross") # 笛卡尔积join关键参数一览:
how:连接策略,inner(默认,取两表匹配行)、left、right、full(不匹配补 null)、cross(笛卡尔积)、semi(仅保留左表有匹配的行,不含右表列)、anti(仅保留左表无匹配的行);on/left_on/right_on:连接键,支持列名、表达式、选择器,两表键名不同时用left_on+right_on;suffix:重名列后缀,默认"_right";validate:连接基数校验,"m:m"(默认,不校验)、"1:1"、"1:m"、"m:1",可发现键不唯一导致的数据错误(注意:流式引擎当前不支持该校验);nulls_equal:是否允许 null 键互相匹配(默认False,null 永不匹配;1.24 版本由join_nulls更名而来);coalesce:是否合并连接列,默认None(除full外都合并);full连接时可通过coalesce=True显式合并两边的键列;maintain_order:结果行的保序策略,none(默认,不保证顺序)、left、right、left_right、right_left;build_side:指定以哪一侧构建哈希表,auto(默认)、prefer_left、prefer_right、force_left、force_right,该参数当前标记为实验性。
df.join(other_df, on="ham", how="full", coalesce=True) df.join(other_df, on="ham", how="semi") df.join(other_df, how="cross")移动与填充:shift、interpolate、upsample、sample、unique、rolling、group_by_dynamic
df.shift(1) # 整体下移一行 df.interpolate() # 线性插值填补缺失 df.sample(n=2) # 随机抽样,支持 frac、with_replacement、seed df.unique(subset=["a"], keep="first") df.rolling(index_column="date", period="2d").agg(pl.col("v").mean())其他:__setitem__(df["col"] = ...原地写列)、pipe(管道式函数组合)、sql(对 DataFrame 执行 SQL 查询,返回LazyFrame)。
select、with_columns、filter、sort等方法均接受**表达式(Expr)**作为核心输入,表达式系统定义于 py-polars/src/polars/expr,底层由 crates/polars-plan/src/dsl 的逻辑计划与 crates/polars-expr 的表达式求值引擎支撑。
杂项(Miscellaneous)与序列化
对应子页面 miscellaneous.rst,包含 7 个方法与序列化子模块:
collect_schema:以惰性方式收集并返回 DataFrame 的 Schema;corr:计算两列相关系数(df.corr(col1, col2));equals:与另一 DataFrame 逐值比较(支持null_equal参数),返回布尔值;lazy:将 eager DataFrame 转为LazyFrame,从而进入惰性查询优化流水线(df.lazy().filter(...).collect());map_columns:对列名批量应用函数;map_rows:对每一行应用函数,返回新的 Series 或 DataFrame。
序列化(Serialization)小节提供两个方法:
df.serialize(file, format="json") # 序列化到 JSON/IPC/二进制 df.deserialize(source, format="json") # 从文件/字节流反序列化serialize/deserialize的format支持"json"、"ipc"、"binary"三种编码(SerializationFormat类型),可持久化 DataFrame 结构以便跨进程传输或长期存储。Python 侧序列化入口见 py-polars/src/polars/_utils/serde.py,Rust 实现位于 crates/polars-python/src/dataframe/serde.rs。
绘图(Plot)与样式(Style)
对应子页面 plot.rst 与 style.rst。二者均通过autoproperty暴露属性而非方法:
DataFrame.plot:返回DataFramePlot对象(定义于 py-polars/src/polars/dataframe/plotting.py),提供与 Altair 联动的声明式绘图 API,例如df.plot.scatter(x="a", y="b"),仅在安装 Altair 后可用;DataFrame.style:返回 great_tables 的GT样式对象(需安装 great_tables),用于生成带格式化、主题、条件着色的 HTML 表格,GT类型定义见 py-polars/src/polars/_typing.py 中对great_tables的导入。
df.plot.bar(x="k", y="v") # 依赖 altair df.style.highlight_max() # 依赖 great_tables两者的可用性检查均通过 py-polars/src/polars/_dependencies.py 中的_ALTAIR_AVAILABLE/_GREAT_TABLES_AVAILABLE标记完成,未安装时会给出明确的升级指引异常。
实现底座:Python 门面与 Rust 内核
从源码结构看,Python 层的DataFrame是一个典型的"门面 + 委托"设计:
- Python 层负责参数校验、类型解析与表达式构建,类定义在 py-polars/src/polars/dataframe/frame.py;
- 真正的列式数据与计算内核位于 Rust 侧,通过 PyO3 绑定暴露为
_plr.PyDataFrame(在frame.py中导入),Rust 侧的数据结构与方法定义见 crates/polars-python/src/dataframe(含general.rs、export.rs、construction.rs、io.rs、serde.rs、map.rs); - 核心算法(哈希分组、排序、连接、聚合)在 crates/polars-core、crates/polars-ops、crates/polars-expr 等 Rust crate 中实现,构成 crates/polars 主 crate 的生态。
例如group_by的 Python 端仅做参数归一化,随后委托PyDataFrame.group_by进入 Rust 侧,由 polars-core 的哈希分组(hashing)模块完成分组键的并行归并;to_pandas、to_numpy则通过 export.rs 中的零拷贝/拷贝策略进行数据搬运。
小结:如何高效使用这份 API 地图
- 快速探索:用
describe、glimpse、show三件套掌握数据概况; - 日常变换:
select/with_columns/filter/sort/unique构成 CRUD 主干,全部以表达式驱动; - 复杂分析:
group_by(含agg、having、map_groups)与join(7 种策略 + 基数校验 + 保序选项)是进阶核心; - 生态衔接:
to_numpy/to_pandas/to_arrow/to_torch/to_jax覆盖主流 Python 数据科学栈; - 持久化:
serialize/deserialize支持 JSON、IPC、二进制三种格式; - 可视化:
plot(Altair)与style(great_tables)让 DataFrame 直接产出图表与样式化表格。
本参考索引覆盖的方法在仓库测试(py-polars/tests/unit)中均有大量验证用例,读者可按分类子页逐个查阅对应方法 docstring 中的 doctest 示例,作为最可靠的"说明书"。
- 数据分析
- 大数据
【免费下载链接】polars
Extremely fast Query Engine for DataFrames, written in Rust
相关推荐
pandas DataFrame 完全参考指南:从构造、索引到统计、绘图与序列化的全量 API 导航
pandas DataFrame 完全参考指南:从构造、索引到统计、绘图与序列化的全量 API 导航 本指南以 pandas 官方 API 参考中 DataFr
数据分析数据科学数据处理python-prompt-toolkit API 参考导航:从 Application 到 Patch Stdout 的完整模块地图
python prompt toolkit API 参考导航:从 Application 到 Patch Stdout 的完整模块地图 导读 reference
CLIPolars DataFrame 聚合方法全解析:逐列归约与水平聚合的 API 语义与底层实现
Polars DataFrame 聚合方法全解析:逐列归约与水平聚合的 API 语义与底层实现 Polars 为 DataFrame 提供了一整套 将整张表归约
数据分析大数据
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考