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

如何在Polars中基于多列创建排名?

解决Polars基于多列生成全局排名的问题

问题分析

你尝试用pl.col("era","pred").rank("ordinal")生成排名时,Polars会对每一列单独计算排名,最终生成两个名为rn的列,这就导致了duplicate name错误。而你需要的是基于era和pred组合的全局排名(先按era排序,再按pred排序后的连续排名)。

解决方案

方法一:用struct组合列后计算排名

将era和pred打包成结构体,Polars会按结构体的字段顺序(先era后pred)进行比较,生成全局唯一的排名列:

import polars as pl

df = pl.DataFrame(
    {   
        "era": ["01", "01", "02", "02", "03", "03"],
        "pred": [3,5,6,8,9,1]
    }
).with_row_index()

result = df.with_columns(
    rn = pl.struct("era", "pred").rank("ordinal")
)
print(result)

输出结果与你的期望完全一致:

shape: (6, 4)
┌───────┬─────┬──────┬─────┐
│ index ┆ era ┆ pred ┆ rn  │
│ ---   ┆ --- ┆ ---  ┆ --- │
│ u32   ┆ str ┆ i64  ┆ u32 │
╞═══════╪═════╪══════╪═════╡
│ 0     ┆ 01  ┆ 3    ┆ 1   │
│ 1     ┆ 01  ┆ 5    ┆ 2   │
│ 2     ┆ 02  ┆ 6    ┆ 3   │
│ 3     ┆ 02  ┆ 8    ┆ 4   │
│ 4     ┆ 03  ┆ 9    ┆ 6   │
│ 5     ┆ 03  ┆ 1    ┆ 5   │
└───────┴─────┴──────┴─────┘

方法二:排序后添加行号(保留原顺序)

如果需要先排序再生成排名,同时保留原DataFrame的行顺序,可以先对排序后的数据集生成行号,再通过关联合并回去:

ranked_df = df.sort(["era", "pred"]).with_row_index(name="rn", offset=1)
result = df.join(ranked_df, on=["index", "era", "pred"])
print(result)

错误原因说明

pl.col("era","pred").rank("ordinal")的逻辑是对era和pred各自独立计算排名,相当于同时执行pl.col("era").rank().alias("rn")和pl.col("pred").rank().alias("rn"),两个列重名导致Polars抛出重复名称错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 04:35:09