如何为Pandas groupby结果添加分组小计并按小计值降序排名?
实现代码
import pandas as pd # 原始数据集 d = {'Col_A': [1,2,3,4,5,6,9,9,10,11,11,12,12,12,12,12,12,13,13], 'Col_B': ['A','K','E','E','H','A','J','A','L','A','B','A','J','C','D','E','A','J','L'], 'Value':[180,120,35,654,789,34,567,21,235,83,234,648,654,234,873,248,45,67,94] } df = pd.DataFrame(data=d) # 1. 先计算每个Col_B的总数值,用于后续降序排序 col_b_total = df.groupby('Col_B')['Value'].sum().sort_values(ascending=False) # 给Col_B添加排序优先级 df['b_sort_order'] = df['Col_B'].map(col_b_total.rank(ascending=False, method='dense').astype(int)) # 2. 定义分组处理函数,生成每个Col_B的明细+小计行 def add_subtotal(group): # 组内明细:按Col_A聚合 detail = group.groupby('Col_A')['Value'].agg(Col_A计数='count', 对应总数值='sum').reset_index() # 生成小计行 subtotal = pd.DataFrame({ 'Col_A': ['*小计'], 'Col_A计数': [detail['Col_A计数'].sum()], '对应总数值': [detail['对应总数值'].sum()] }) # 合并明细和小计 res = pd.concat([detail, subtotal], ignore_index=True) # 保留Col_B和排序字段 res['Col_B'] = group.name res['b_sort_order'] = group['b_sort_order'].iloc[0] return res # 3. 按Col_B分组处理,再按排序字段排序,最后调整列顺序 result = df.groupby('Col_B', sort=False).apply(add_subtotal).reset_index(drop=True) result = result.sort_values(['b_sort_order', 'Col_A'], na_position='last').drop(columns='b_sort_order') result = result[['Col_B', 'Col_A', 'Col_A计数', '对应总数值']] # 输出结果 print(result)
关键逻辑说明
- 先计算每个Col_B的Value总和作为排序依据,保证最终展示时Col_B分类按总数值降序排列
- 分组处理时为每个Col_B单独生成明细行和小计行,小计行的
Col_A标记为*小计方便识别 - 明细行里的
Col_A计数固定为1(题目说明Col_A和Col_B组合唯一),小计行的Col_A计数就是该Col_B下不同Col_A的总数量 - 如果需要更紧凑的多层索引展示格式,可以额外执行
result.set_index(['Col_B', 'Col_A'])调整格式
内容的提问来源于stack exchange,提问作者Jiamei
相关产品推荐
相关产品推荐

