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

Pandas中实现排除行列顶级MultiIndex相同的单元格进行行求和

Pandas中实现排除行列顶级MultiIndex相同的单元格进行行求和

我完全懂你的需求啦——就是在带有双层MultiIndex的DataFrame里,计算行总和的时候,要排除掉那些列的顶级索引和行的顶级索引相同的单元格,对吧?看你已经尝试用循环来实现,但结果不对,我来给你两个实用的方法,尤其是第二个适合大数据量的场景,效率会高很多。

首先先还原一下你的数据构造(方便大家理解问题):

import pandas as pd

label_columns1 = ['Country1','Country2']
label_columns2 = ['agri1', 'agri2']
label_rows1 = ['Country1','Country2']
label_rows2 = ['agri1', 'agri2']

df = pd.DataFrame(
    [[1,2,3,4]]*4,
    index=pd.MultiIndex.from_product([label_rows1,label_rows2]),
    columns=pd.MultiIndex.from_product([label_columns1, label_columns2 ])
)

你的问题核心是:对每一行来说,只保留列顶级索引和行顶级索引不同的列进行求和。比如Country1开头的行,要排除Country1列组的所有值,只加Country2列组的数值;Country2开头的行则相反。

方法一:用apply逐行筛选(简单直观)

这个方法逻辑很直接,对每一行,筛选出列顶级索引不等于行顶级索引的列,再求和:

# 先提取所有列的顶级索引
col_top_level = df.columns.get_level_values(0)

# 对每行计算符合条件的列的和
df[('Total', 'Value')] = df.apply(
    lambda row: row[col_top_level != row.name[0]].sum(),
    axis=1
)

这里row.name[0]就是当前行的顶级索引(比如Country1),col_top_level != row.name[0]会生成一个布尔数组,帮我们精准筛选出需要求和的列。

运行后你会得到想要的结果:

Country1     Country2      Total
                   agri1 agri2   agri1 agri2 Value
Country1 agri1        1     2       3     4     7
         agri2        1     2       3     4     7
Country2 agri1        1     2       3     4     3
         agri2        1     2       3     4     3

方法二:批量运算(适合大数据量)

如果你的DataFrame行数特别多,apply逐行处理的效率会比较低,这时候可以用批量计算的方式:先算所有列的总和,再减去和行顶级索引相同的列组的总和,这样结果是一样的,但速度快很多:

# 先计算每行所有列的总和
total_all = df.sum(axis=1)

# 获取所有顶级国家名称
countries = df.columns.get_level_values(0).unique()

# 计算每行中,和行顶级索引相同的列组的总和
same_country_total = pd.Series(0, index=df.index)
for country in countries:
    same_country_total += df.loc[:, country].sum(axis=1)

# 最终的Total = 所有列总和 - 相同顶级索引的列组总和
df[('Total', 'Value')] = total_all - same_country_total

为什么你的循环没生效?

你之前写的循环逻辑有问题:

for col in df.columns:
    for row in df.index:
        if col != row:
            df[('Total',"Value")] = df.sum(axis=1)

这里每次判断col != row后,直接赋值了整行的总和(没有筛选列),而且循环会反复覆盖Total列,最后得到的还是所有列的总和,根本没排除掉目标列,所以达不到预期效果。

备注:内容来源于stack exchange,提问作者埃塞ABELA

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.22 09:28:08