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

如何基于两列分组去重,为col2生成col1组内统一排名列

问题描述

现有如下DataFrame:

import pandas as pd

df = pd.DataFrame({'col1': ['A', 'A', 'A', 'A', 'B', 'C', 'C'],
                   'col2': ['a1', 'a1', 'a2', 'a2', 'b1', 'c1', 'c2']})
print(df)

输出:

col1 col2
0    A   a1
1    A   a1
2    A   a2
3    A   a2
4    B   b1
5    C   c1
6    C   c2

需求:新增一列col3,用于标识col2在每个col1分组内的排名,同一col1分组中相同的col2值需对应相同的排名。

尝试了以下三段代码,均未得到正确结果:

df['col3_1'] = df.groupby(['col1', 'col2']).cumcount() + 1
df['col3_2'] = df.groupby(['col1'])['col2'].cumcount() + 1
df['col3_3'] = df.groupby(['col1', 'col2']).ngroup() + 1

print(df)

输出:

col1 col2  col3_1  col3_2  col3_3
0    A   a1       1       1       1
1    A   a1       2       2       1
2    A   a2       1       3       2
3    A   a2       2       4       2
4    B   b1       1       1       3
5    C   c1       1       1       4
6    C   c2       1       2       5

注:col2的实际值无固定格式规律。

预期输出:

col1 col2  col3
0    A   a1     1
1    A   a1     1
2    A   a2     2
3    A   a2     2
4    B   b1     1
5    C   c1     1
6    C   c2     2
解决方案

方法1:使用groupby + rank(method='dense')

rank方法的method='dense'参数会生成连续的排名,相同值获得相同排名且排名不会跳过数字,正好匹配需求:

df['col3'] = df.groupby('col1')['col2'].rank(method='dense', ascending=True).astype(int)

方法2:使用factorize结合transform

factorize会将分组内的唯一值映射为连续整数(从0开始),通过transform将映射结果应用到原DataFrame每一行,最后加1调整为从1开始的排名:

df['col3'] = df.groupby('col1')['col2'].transform(lambda x: pd.factorize(x)[0] + 1)

原代码错误原因说明

  • col3_1:按col1+col2分组后用cumcount,是统计每个子分组内的行序号,同一col2值会生成递增数字,不符合“相同值同排名”要求
  • col3_2:按col1分组后对col2用cumcount,是统计分组内每行的顺序号,不管值是否重复,因此逐个递增
  • col3_3:ngroup是给全局所有col1+col2组合分配唯一编号,不是分组内的排名,编号会跨分组连续递增

运行上述任一正确方法后,均可得到预期输出。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 13:22:03