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

如何在Pandas DataFrame中新增列展示分组/子组基于值总和的排名

如何在Pandas DataFrame中新增列展示分组/子组基于值总和的排名

这问题我之前处理类似需求时也碰到过,核心思路其实很清晰:先算出每个(group, subgroup)组合的总值,给这些总值排好名,最后把排名映射回原数据的每一行就行。我结合你的示例给你一步步拆解:

首先先重现你的示例数据:

import pandas as pd

df = pd.DataFrame({
        "group": ["a", "a", "a", "a", "a", "b", "b", "b", "b", "b","c"],
        "subgroup": ["i","ii","i","ii","i","ii","i","ii","i","ii","ii"],
        "value": [2, 4, 2, 3, 5, 1, 2, 4, 1, 5, 11] })

步骤1:计算每个分组的总值

我们用groupby按group和subgroup分组,对value求和,转成DataFrame方便后续处理:

# 计算每个(group, subgroup)的value总和
group_totals = df.groupby(['group', 'subgroup'])['value'].sum().reset_index(name='total_value')

这时候group_totals的结果是:

groupsubgrouptotal_value
ai9
aii7
bi3
bii10
cii11

步骤2:给分组总值计算排名

我们需要按总值从大到小排名(1为最高),用Pandas的rank方法,设置ascending=False表示降序,转成整数让排名更直观:

# 按总值降序排名,1对应最大的总值
group_totals['rank'] = group_totals['total_value'].rank(ascending=False, method='min').astype(int)

这里的method='min'是为了处理并列场景(如果多个组总值相同,会给它们分配相同的最小排名),你的示例里没有并列,但加上后代码更通用。现在group_totals就有了我们需要的rank列:

groupsubgrouptotal_valuerank
ai93
aii74
bi35
bii102
cii111

步骤3:把排名合并回原DataFrame

用merge方法,根据group和subgroup两个字段匹配,把rank列映射到原数据的每一行:

# 合并排名到原数据
result = df.merge(group_totals[['group', 'subgroup', 'rank']], on=['group', 'subgroup'], how='left')

现在你可以打印result,就得到了和你预期完全一致的输出:

print(result.to_markdown(index=False))

输出表格:

groupsubgroupvaluerank
ai23
aii44
ai23
aii34
ai53
bii12
bi25
bii42
bi15
bii52
cii111

如果你喜欢更简洁的链式写法,也可以把步骤合并成一行(可读性稍弱,但代码更紧凑):

result = df.merge(
    df.groupby(['group', 'subgroup'])['value']
      .sum()
      .reset_index(name='total')
      .assign(rank=lambda x: x['total'].rank(ascending=False, method='min').astype(int))
    [['group', 'subgroup', 'rank']],
    on=['group', 'subgroup'],
    how='left'
)

这个方法效率很高,因为groupby和merge都是Pandas优化后的操作,即使处理大数据量也能快速完成。

备注:内容来源于stack exchange,提问作者nikto

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 10:34:36