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

如何在Polars中按分区、多列排序生成Row_Number式排名列

在Polars中实现类似SQL ROW_NUMBER()的分区排名

要实现SQL中ROW_NUMBER() OVER(PARTITION BY Sector ORDER BY month_number ASC, id ASC)的效果,Polars有几种简洁的实现方式,核心是利用窗口函数并指定分区和排序规则:

方法1:使用pl.rank()(推荐)

pl.rank(method="ordinal")完全对应SQL的ROW_NUMBER()逻辑,会为每个分区内的行生成唯一的递增序号,无并列值:

import polars as pl

data = {
    'id' : [1,2,3,4,5,1,2,3,4,5] ,
    'month' : [1,1,1,1,1,2,2,2,2,2] ,
    'sales' : [20.1, 34.7, 89.4, 932.65, 12.7, 65.2, 893.2, 89.2, 12.0, 12.25],         
    'sector' : ['sec1', 'sec1', 'sec1', 'sec1', 'sec1', 'sec2', 'sec2', 'sec2', 'sec2', 'sec2'],      
}

df = pl.DataFrame(data)

# 生成rank列
result = df.with_columns(
    pl.rank(method="ordinal")
    .over(pl.partition_by("sector").order_by("month", "id"))
    .alias("rank")
)

# 按期望格式排序(可选,匹配示例输出顺序)
result = result.sort("sector", "month", "id")

print(result)

方法2:修复你的cum_sum()方案

你之前尝试的cum_sum()方法是可行的,但需要在窗口中明确指定排序规则,而非仅分区:

result = df.with_columns(
    pl.lit(1)
    .cum_sum()
    .over(pl.partition_by("sector").order_by("month", "id"))
    .alias("rank")
).sort("sector", "month", "id")

方法3:使用int_range()生成连续序号

通过pl.int_range结合窗口内的计数,也能生成行号:

result = df.with_columns(
    pl.int_range(1, pl.count() + 1)
    .over(pl.partition_by("sector").order_by("month", "id"))
    .alias("rank")
).sort("sector", "month", "id")

输出验证

以上方法均会生成符合期望的输出:

shape: (10, 5)
┌──────┬─────┬───────┬────────┬──────────────┐
│ rank ┆ id  ┆ month ┆ sector ┆ sales        │
│ ---  ┆ --- ┆ ---   ┆ ---    ┆ ---          │
│ i64  ┆ i64 ┆ i64   ┆ str    ┆ f64          │
╞══════╪═════╪═══════╪════════╪══════════════╡
│ 1    ┆ 1   ┆ 1     ┆ sec1   ┆ 20.1         │
│ 2    ┆ 2   ┆ 1     ┆ sec1   ┆ 34.7         │
│ 3    ┆ 3   ┆ 1     ┆ sec1   ┆ 89.4         │
│ 4    ┆ 4   ┆ 1     ┆ sec1   ┆ 932.65       │
│ 5    ┆ 5   ┆ 1     ┆ sec1   ┆ 12.7         │
│ 1    ┆ 1   ┆ 2     ┆ sec2   ┆ 65.2         │
│ 2    ┆ 2   ┆ 2     ┆ sec2   ┆ 893.2        │
│ 3    ┆ 3   ┆ 2     ┆ sec2   ┆ 89.2         │
│ 4    ┆ 4   ┆ 2     ┆ sec2   ┆ 12.0         │
│ 5    ┆ 5   ┆ 2     ┆ sec2   ┆ 12.25        │
└──────┴─────┴───────┴────────┴──────────────┘

关键说明

  • 你之前的尝试失败是因为仅在over()中指定了分区sector,未添加order_by,导致cum_sum()按DataFrame原始顺序累加,而非month+id排序后的顺序。
  • Polars的窗口函数支持链式调用partition_by().order_by(),完全对应SQL窗口的PARTITION BY和ORDER BY语法。
  • 最后的sort()仅为匹配示例输出顺序,若业务逻辑不需要固定展示顺序,可省略。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 05:47:44