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

如何获取多层索引DataFrame的列均值并保持列顺序?

多层索引DataFrame按指定索引计算均值并保持列顺序

问题需求

对多层索引的DataFrame,按某一层重复出现的索引值(比如年份)计算各数值列的均值,同时需要保持原有的列顺序。

示例说明

创建示例多层索引DataFrame

import pandas as pd

# 创建示例DataFrame
df = pd.DataFrame({'A': ['A', 'A', 'A','B', 'B', 'B'],
                   'B': ['2000','2001','2002','2000','2001','2002'],
                   'C': [1, 2, 3, 4, 5, 6],
                   'D': [4, 5, 6, 7, 8, 9]})

# 将A(国家)和B(年份)设置为多层索引
df = df.set_index(['A', 'B'])

目标结果

需要得到以年份为索引,C、D列对应年份所有国家均值的DataFrame:

desired_df = pd.DataFrame({'B': ['2000','2001','2002'],
                   'C': [2.5, 3.5, 4.5],
                   'D': [5.5, 6.5, 7.5]})

尝试的方法

使用pivot_table计算均值,但实际处理数据时发现列顺序发生了变化:

desired_df=df.pivot_table(values=df.columns, index='B', aggfunc='mean')

实际数据场景

以下是处理世界银行数据的可复现代码,目标是计算除中国外其他国家的年份均值:

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import os
import wbdata as wb
from sklearn.linear_model import LinearRegression
from textwrap import wrap

country = ['CHN','DEU','USA','KOR','JPN']

# 定义世界银行指标
indicators={'SE.TER.ENRR' : '高等教育毛入学率(%)',
           'SP.URB.TOTL.IN.ZS' : '城市人口占总人口比重(%)',
           'IP.JRN.ARTC.SC' : '科技出版物数量',
           'IP.PAT.RESD' : '居民专利申请量',
           'GB.XPD.RSDV.GD.ZS' : '研发支出占GDP比重(%)',
           'BM.KLT.DINV.WD.GD.ZS' : '对外直接投资净流出占GDP比重(%)',
           'TX.VAL.TECH.MF.ZS' : '高科技产品出口占制造业出口比重(%)',
           'NV.MNF.TECH.ZS.UN' : '中高技术制造业增加值占制造业增加值比重(%)',
           'NV.IND.TOTL.ZS' : '工业增加值占GDP比重(%)',
           'SP.POP.TOTL':'总人口'}

# 获取数据并处理
df=wb.get_dataframe(indicators, country = country)
df=df.sort_index()

# 计算人均指标
df['人均科技出版物数量']=df['科技出版物数量']/df['总人口']
df['人均居民专利申请量']=df['居民专利申请量']/df['总人口']

# 处理中国数据
df_china = df[df.index.isin(['China'], level=0)]
df_china = df_china.reset_index()
df_china=df_china.set_index('date')

# 指定列顺序
valores =['高等教育毛入学率(%)',
       '城市人口占总人口比重(%)',
       '研发支出占GDP比重(%)',
       '对外直接投资净流出占GDP比重(%)',
       '高科技产品出口占制造业出口比重(%)',
       '中高技术制造业增加值占制造业增加值比重(%)',
       '工业增加值占GDP比重(%)',
       '人均科技出版物数量',
       '人均居民专利申请量']

df_china=df_china[valores]

# 处理其他国家数据并计算均值(此处pivot_table会改变列顺序)
df_resto = df[df.index.isin(['United States','Germany','Japan','Korea, Rep.'], level=0)]
df_resto = df_resto.reset_index()
df_resto=df_resto.set_index('date')
df_resto = df_resto[valores]

df_resto=df_resto.pivot_table(values=valores, index='date', aggfunc='mean')

解决方案

方法1:使用groupby(推荐,天然保留列顺序)

groupby会自动保持原DataFrame的列顺序,无需额外处理:

针对示例DataFrame

# 按多层索引中的'B'(年份)分组计算均值
desired_df = df.groupby(level='B').mean()

针对实际数据中的df_resto

如果df_resto是重置索引后的单索引(date为索引):

df_resto = df_resto.groupby('date').mean()

如果df_resto未重置索引,仍是多层索引(国家、date):

df_resto = df_resto.groupby(level='date').mean()

方法2:使用pivot_table后重新指定列顺序

若坚持使用pivot_table,计算完成后通过原列名列表重新排序即可恢复顺序:

针对示例DataFrame

desired_df = df.pivot_table(values=df.columns, index='B', aggfunc='mean')[df.columns]

针对实际数据中的df_resto

df_resto = df_resto.pivot_table(values=valores, index='date', aggfunc='mean')[valores]

内容的提问来源于stack exchange,提问作者Mario Diez Martínez

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 19:30:38