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

如何将DataFrame索引中的小计标签拆分至列并清理合并字符串?

解决DataFrame小计行的索引拆分与字符串清理问题

问题描述

我有一个包含多列的大型DataFrame,在创建列小计行时遇到两个问题:

  • 小计行的标识标签位于索引而非DataFrame的列中
  • 求和操作导致非数值列合并成了字符串

我的目标:

  1. 拆分索引中的小计标识字符串,将对应内容放入指定列
  2. 清除小计行最右侧非数值列中的合并字符串

原始代码

import pandas as pd

df = pd.DataFrame( {'Status':['Active','Active','Inactive','Active'], 'Source':['Domestic','International','International','Restricted'], 'Activity':['In Progress','Post','Post','In Progress'], 'FY20':[2,55,52,99],'FY21':[90,20,11,43],'FY22':[10,52,57,9]})

# 排序设置
df['Status'] = pd.Categorical(df['Status'],categories= ['Inactive','Active'])
df = df.sort_values('Status')
df['Source'] = pd.Categorical(df['Source'],categories= ['International','Restricted','Domestic'])
df = df.sort_values('Source')

# 计算列的总和并添加小计行
df.loc['Active - In Progress Subtotal'] = df.loc[(df['Status'].isin(['Active'])) & (df['Activity'].isin(['In Progress']))].sum(axis=0)

期望输出

最终得到的DataFrame需要将小计信息放入对应列,且非数值列无合并字符串,排序后结果如下:

import pandas as pd

df = pd.DataFrame( {'Status':['Active','Active','Inactive','Active','Active'], 'Source':['Domestic','International','International','Restricted','In Progress Subtotal'], 'Activity':['In Progress','Post','Post','In Progress',""], 'FY20':[2,55,52,99,101],'FY21':[90,20,11,43,133],'FY22':[10,52,57,9,19]})

df['Status'] = pd.Categorical(df['Status'],categories= ['Inactive','Active'])
df = df.sort_values('Status')
df['Source'] = pd.Categorical(df['Source'],categories= ['International','Restricted','Domestic','In Progress Subtotal'])
df = df.sort_values('Source')

解决方案

核心思路

  • 仅对数值列执行求和操作,避免非数值列被合并为字符串
  • 手动构造小计行的非数值列内容,直接将拆分后的标识放入对应列
  • 更新分类变量,确保小计行排序位置正确

修正后的完整代码

import pandas as pd

# 初始化原始DataFrame
df = pd.DataFrame( {'Status':['Active','Active','Inactive','Active'], 
                    'Source':['Domestic','International','International','Restricted'], 
                    'Activity':['In Progress','Post','Post','In Progress'], 
                    'FY20':[2,55,52,99],'FY21':[90,20,11,43],'FY22':[10,52,57,9]})

# 设置初始分类排序规则
df['Status'] = pd.Categorical(df['Status'], categories=['Inactive','Active'])
df['Source'] = pd.Categorical(df['Source'], categories=['International','Restricted','Domestic'])
df = df.sort_values(['Status', 'Source'])

# 筛选目标行并仅对数值列求和
filter_condition = (df['Status'] == 'Active') & (df['Activity'] == 'In Progress')
subtotal_numeric = df.loc[filter_condition, ['FY20', 'FY21', 'FY22']].sum(axis=0)

# 构造完整的小计行数据
subtotal_row = pd.Series({
    'Status': 'Active',
    'Source': 'In Progress Subtotal',
    'Activity': '',
    **subtotal_numeric.to_dict()
})

# 将小计行添加到DataFrame,忽略索引以保持连续性
df = pd.concat([df, subtotal_row.to_frame().T], ignore_index=True)

# 更新Source的分类规则,加入小计标签
df['Source'] = pd.Categorical(df['Source'], 
                              categories=['International','Restricted','Domestic','In Progress Subtotal'])
# 重新排序
df = df.sort_values(['Status', 'Source'])

# 查看结果
print(df)

代码说明

  1. 数值列单独求和:仅对FY20、FY21、FY22列求和,避免Status、Source等非数值列被sum操作合并为字符串
  2. 手动构造小计行:直接设置小计行的Status为Active,Source为In Progress Subtotal,Activity为空字符串,完全匹配需求
  3. 连续索引维护:使用pd.concat添加行并设置ignore_index=True,避免原方法中索引存标识的问题
  4. 分类规则更新:在Source的分类中加入小计标签,确保排序后小计行处于指定位置

内容的提问来源于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 22:53:17