You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Polars中实现pandas的ngroup功能并分配组ID

在Polars中高效实现pandas的.ngroup()功能

需求说明

给DataFrame的指定分组列分配连续整数ID(从0开始),对应pandas中groupby().ngroup()的功能,且方案需支持百万级规模数据集的高效处理。

示例数据集

import polars as pl

df = pl.DataFrame(
     {"group_a": ["a", "aa", "a"], "group_b": ["b", "bb", "b"], "val": [1, 2, 3]}
)

最优实现方案

方案1:使用factorize()(推荐)

factorize()是Polars专门用于生成唯一分组ID的矢量化方法,内存效率极高,适合大规模数据:

df = df.with_columns(
    # factorize返回元组,第一个元素是每行对应的分组ID(从0开始)
    pl.col(["group_a", "group_b"]).factorize()[0].alias("new_group")
)

方案2:使用窗口函数dense_rank()

通过窗口函数实现连续排名,调整起始值后与ngroup效果一致:

df = df.with_columns(
    # dense_rank默认从1开始,减1转为0起始的ID
    (pl.dense_rank().over(["group_a", "group_b"]) - 1).alias("new_group")
)

执行结果

两种方案均会得到期望输出:

shape: (3, 4)
┌─────────┬─────────┬─────┬───────────┐
│ group_a ┆ group_b ┆ val ┆ new_group │
│ ---     ┆ ---     ┆ --- ┆ ---       │
│ str     ┆ str     ┆ i64 ┆ i64       │
╞═════════╪═════════╪═════╪═══════════╡
│ a       ┆ b       ┆ 1   ┆ 0         │
│ aa      ┆ bb      ┆ 2   ┆ 1         │
│ a       ┆ b       ┆ 3   ┆ 0         │
└─────────┴─────────┴─────┴───────────┘

临时方案的问题分析

你之前的临时方案通过unique提取分组、生成ID后join回去,存在核心缺陷:

  • 需要生成中间唯一分组数据集,当百万级数据包含大量唯一分组时,会占用大量内存;
  • join操作的时间和内存开销极高,容易引发OOM(内存不足)崩溃。

上述两种最优方案均为矢量化操作,无需额外中间数据,完全在Polars查询引擎中高效处理,能够轻松应对大规模数据集。

内容的提问来源于stack exchange,提问作者nleh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 03:25:27