
本文介绍如何使用 pandas 为 dataframe 高效添加一列,该列反映每个 (group, subgroup) 组合基于 value 列总和的全局排名(降序),适用于多级分组排序场景。
本文介绍如何使用 pandas 为 dataframe 高效添加一列,该列反映每个 (group, subgroup) 组合基于 value 列总和的全局排名(降序),适用于多级分组排序场景。
在数据分析中,常需对嵌套分组(如 group → subgroup)按某指标聚合后进行全局排序,并将排序结果回填至原始数据。例如,给定一个包含 group、subgroup 和 value 的 DataFrame,目标是新增 rank 列,其值表示该 (group, subgroup) 对应的 value 总和在整个数据集中的降序排名(即总和越大,排名越靠前,排名为 1 表示最高)。
实现的关键在于三步链式操作:分组聚合 → 全局排序 → 关联回填。具体如下:
-
按
(group, subgroup)分组并求value总和:df.groupby(['group', 'subgroup'])['value'].sum()
输出为
Series,索引为 MultiIndex(group, subgroup),值为对应子组总和。 -
对总和序列进行降序排名:
.rank(ascending=False)
默认使用
method='average'(并列取平均),若需整数排名(如并列时取最小名次),可改用method='min'。此处ascending=False确保总和最大者得 rank=1。 -
重命名并重置索引,再与原表合并:
.rename('rank').reset_index() df.merge(..., on=['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]
})
# 生成 rank 列:按 (group, subgroup) 汇总 value 后降序排名
rank_series = df.groupby(['group', 'subgroup'])['value'].sum().rank(ascending=False)
out = df.merge(
rank_series.rename('rank').reset_index(),
on=['group', 'subgroup']
)
print(out)
输出结果中 rank 列为浮点类型(如 3.0),若需整数形式,可在合并后添加 .astype(int),但需注意:当存在并列总和时,rank() 默认返回平均排名(如两个并列第2则均为2.5),此时转为 int 会截断小数。如需严格整数且保留并列逻辑,建议显式指定 method 参数:
-
method='min':并列项取最小名次(如两个第2则均为2); -
method='dense':并列后名次连续(如两个第2,则下一名为3)。
此外,该方法时间复杂度为 O(n + k log k)(k 为唯一子组数),远优于手动循环或 apply,是处理大规模数据的推荐方案。










