如何基于自定义聚合逻辑高效去除Polars DataFrame重复行?
优化Polars自定义去重聚合的实现
你当前的循环分组方法虽然能得到正确结果,但没有利用Polars的向量化运算优势,导致性能低下——Polars的核心优势就是批量处理数据,循环遍历每个分组会拆解DataFrame,抵消引擎优化效果,还会增加内存和拼接开销。
最优实现:直接用group_by + agg批量聚合
不需要循环,直接通过group_by指定去重列,然后在agg中针对不同列类型定义聚合逻辑,Polars会自动完成向量化处理,性能提升显著:
import polars as pl df = pl.DataFrame( { "id": [0, 0, 0, 1, 1], "color": ["red", "green", "green", "red", "red"], "shape": ["square", "triangle", "square", "triangle", "square"], "size": [2, 4, 6, 1, 3] } ) # 直接分组聚合,一步到位 df_dedup = df.group_by("id", maintain_order=True).agg( # 类别列(字符串)取众数的第一个结果 pl.col(["color", "shape"]).mode().first(), # 数值列取均值 pl.col("size").mean() ) print(df_dedup)
输出结果
shape: (2, 4) ┌─────┬───────┬──────────┬──────┐ │ id ┆ color ┆ shape ┆ size │ │ --- ┆ --- ┆ --- ┆ --- │ │ i64 ┆ str ┆ str ┆ f64 │ ╞═════╪═══════╪══════════╪══════╡ │ 0 ┆ green ┆ square ┆ 4.0 │ │ 1 ┆ red ┆ triangle ┆ 2.0 │ └─────┴───────┴──────────┴──────┘
通用化优化(自动识别列类型)
如果你的DataFrame列很多,不想手动指定列名,可以通过列类型自动匹配聚合逻辑:
df_dedup = df.group_by("id", maintain_order=True).agg( # 所有字符串/类别列取众数 pl.col(pl.STRING | pl.CATEGORICAL).mode().first(), # 所有数值列取均值 pl.col(pl.NUMERIC).mean() )
性能提升原因
- 向量化运算:Polars会把所有分组的聚合操作批量执行,避免了循环中单个分组的零散计算
- 无额外拼接开销:直接生成最终结果,不需要创建临时列表再
concat - 引擎优化:
group_by+agg是Polars高度优化的核心操作,内部使用Arrow引擎加速,远快于Python循环
内容的提问来源于stack exchange,提问作者RCap107
相关产品推荐
相关产品推荐

