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

如何聚合MultiIndexed Pandas DataFrame指定行子集并追加汇总行?

问题设置与目标

我有一个如下所示的MultiIndexed Pandas DataFrame:

import pandas as pd

df = pd.DataFrame({
    'Values':[1, 3, 4, 8, 5, 2, 9, 0, 2],
    'A':['A1', 'A1', 'A1', 'A1', 'A2', 'A2', 'A3', 'A3', 'A3'],
    'B':['foo', 'bar', 'fab', 'baz', 'foo', 'baz', 'qux', 'baz', 'bar']
})
df.set_index(['A','B'], inplace=True)
print(df.to_string())

输出结果:

Values
A  B          
A1 foo       1
   bar       3
   fab       4
   baz       8
A2 foo       5
   baz       2
A3 qux       9
   baz       0
   bar       2

我的最终目标是用最简单、最标准的Pandas方法,将B列中所有"bar"和"baz"行替换为名为"other"的求和行(如下所示):

Values
A  B          
A1 foo       1
   fab       4
   other    11
A2 foo       5
   other     2
A3 qux       9
   other     2
当前进展

我已经学会了为MultiIndex DataFrame创建掩码,标记需要聚合的行(这些行在agg_list中):

agg_list = ['bar', 'baz']
# 创建掩码,标记B列中属于agg_list的行
filterFunc = lambda x: x.index.get_level_values('B') in agg_list
mask = df.groupby(level=['A','B']).apply(filterFunc)

生成的掩码如下:

A   B  
A1  bar     True
    baz     True
    fab    False
    foo    False
A2  baz     True
    foo    False
A3  bar     True
    baz     True
    qux    False

我也知道如何移除不需要的行:

# 使用掩码移除B列中属于agg_list的行
df_masked = df[[~mask.loc[i1, i2] for i1,i2 in df.index]]
print(df_masked.to_string())

输出结果:

Values
A  B          
A1 foo       1
   fab       4
A2 foo       5
A3 qux       9

但我不知道如何对这些被标记的行进行聚合求和,并将结果作为"other"行追加到每个A分组中。

类似问题与解决方案

我见过思路类似的非MultiIndex场景解决方案,但无法直接套用:

threshold = 6
m = df['value'] < threshold
df1 = df[~m].copy()
df1.loc['Z'] = df.loc[m, 'value'].sum()

或者:

m = df['value'] < threshold
df1 = df[~m].append(df.loc[m, ['value']].sum().rename('Z'))
解决方案

这里提供两种简洁的标准实现方式:

方法一:分组聚合后合并

先提取并保留不需要聚合的行,再对目标行按A分组求和并设置新索引,最后合并排序:

agg_list = ['bar', 'baz']

# 提取需要保留的行(B值不在agg_list中)
df_keep = df[~df.index.get_level_values('B').isin(agg_list)]

# 对目标行按A分组求和,将B列设置为"other"并追加索引
df_other = df[df.index.get_level_values('B').isin(agg_list)] \
            .groupby(level='A').sum() \
            .assign(B='other') \
            .set_index('B', append=True)

# 合并两个数据集并按索引排序
result = pd.concat([df_keep, df_other]).sort_index()
print(result.to_string())

方法二:替换后分组求和

先将B列中的目标值替换为"other",再按A和B分组求和,一步到位:

agg_list = ['bar', 'baz']

# 重置索引后替换B列的目标值
df_copy = df.reset_index()
df_copy['B'] = df_copy['B'].replace(agg_list, 'other')

# 按A和B分组求和,重新设置多级索引
result = df_copy.groupby(['A', 'B']).sum().sort_index()
print(result.to_string())

两种方法都能得到预期结果,其中方法二更简洁,适合这类替换后聚合的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 05:24:08