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

如何按指定规则自动排序含Subtotal行的DataFrame?

实现带Subtotal行的DataFrame自动排序方案

问题描述

需要对大规模DataFrame进行自动化排序,使多处Subtotal行处于对应分组的正确位置(即同分组非汇总行之后,上层汇总行在对应子分组全部完成之后)。

原始未排序DataFrame

import pandas as pd

df = pd.DataFrame( {'Comp':['Active','Active','Active','Active','BRAKE','Active','Active','Active','BRAKE','Active','Active','Active','Active'],
                     'Source':['Env-IRP','Env-IRP','Env-IRP','Env-MM','BRAKE-IRP','Env-MM','Env-IRP','Env-MM','BRAKE-IRP','Env-IRP','Env-IRP','Env-MM','Env-MM'],
                        'ActCat':['Inv','Inv','RA','Inv','Inv','RA','','','','Inv','RA','Inv','RA'],
                          'Act':['foo','eggs','buzz','buzz','foo','eggs','Subtotal','Subtotal','Subtotal','Subtotal','Subtotal','Subtotal','Subtotal'],
                          'OG20':[1,2,3,4,5,6,6,10,5,3,3,4,6],
                          'OG21':[1,2,3,4,5,6,6,10,5,3,3,4,6],'OG22':[1,2,3,4,5,6,6,10,5,3,3,4,6]})

已尝试的代码

df['sort_helper'] = df['Act'].apply(lambda x: 1 if x == "Subtotal" else 0)
df.sort_values(by=['Comp','Source','ActCat','sort_helper','Act'], inplace=True)

期望输出

df = pd.DataFrame( {'Comp':['Active','Active','Active','Active','Active','Active','Active','Active','Active','Active','Active','Active','BRAKE','BRAKE','BRAKE','BRAKE'],
                     'Source':['Env-IRP','Env-IRP','Env-IRP','Env-IRP','Env-IRP','Env-IRP','Env-MM','Env-MM','Env-MM','Env-MM','Env-MM','','BRAKE-IRP','BRAKE-IRP','BRAKE-IRP',''],
                        'ActCat':['Inv','Inv','Inv','RA','RA','','Inv','Inv','RA','RA','','','Inv','Inv','',''],
                          'Act':['foo','eggs','Subtotal','buzz','Subtotal','Subtotal','buzz','Subtotal','eggs','Subtotal','Subtotal','Subtotal','foo','Subtotal','Subtotal','Subtotal'],
                          'OG20':[1,2,3,3,3,6,4,4,6,6,10,16,6,6,6,6],
                          'OG21':[1,2,3,3,3,6,4,4,6,6,10,16,6,6,6,6],'OG22':[1,2,3,3,3,6,4,4,6,6,10,16,6,6,6,6]})

解决方案

核心思路是通过排序辅助键确保Subtotal始终处于同分组最后,同时利用Pandas空值排序特性处理上层汇总行。

基础实现方案

# 生成排序辅助键:Subtotal标记为1,其余为0,确保汇总行在同分组最后
df['sort_key'] = df['Act'].map(lambda x: 1 if x == 'Subtotal' else 0)

# 按层级分组维度排序,空值默认排在最后,匹配上层汇总逻辑
df_sorted = df.sort_values(
    by=['Comp', 'Source', 'ActCat', 'sort_key', 'Act'],
    na_position='last'
).drop('sort_key', axis=1)

# 输出结果
print(df_sorted)

保持非汇总行原始顺序的变种

如果需要保留同分组内非Subtotal行的原始顺序,可通过groupby生成组内序号替代Act作为排序键:

# 生成组内序号,保留原始顺序
df['group_seq'] = df.groupby(['Comp', 'Source', 'ActCat'])['Act'].cumcount()
df['sort_key'] = df['Act'].map(lambda x: 1 if x == 'Subtotal' else 0)

# 按层级+辅助键+组内序号排序
df_sorted = df.sort_values(
    by=['Comp', 'Source', 'ActCat', 'sort_key', 'group_seq'],
    na_position='last'
).drop(['sort_key', 'group_seq'], axis=1)

方案说明

  1. sort_key的作用:让同分组内所有非汇总行优先排序,Subtotal行紧随其后
  2. 层级排序维度:Comp→Source→ActCat严格对应分组层级,确保同类别行聚集
  3. 空值处理:na_position='last'让空值的分组行(如空ActCat、空Source)排在对应子分组之后,正好匹配上层汇总的Subtotal逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 08:20:58