PandasMultiIndexDataFrame多级自定义分组聚合实战教程

2026年04月21日/ 浏览 7

Pandas MultiIndex DataFrame 多级自定义分组聚合实战教程

在数据分析工作中,我们经常需要处理结构复杂的数据集。当数据具有多个维度、存在嵌套关系时,Pandas 的 MultiIndex(多级索引)就成为不可或缺的工具。尤其在面对电商销售记录、用户行为日志或金融时间序列等场景中,数据往往天然具备层级结构。本文将带你深入理解如何利用 MultiIndex 实现灵活的自定义分组与聚合操作。

假设我们有一份电商平台的销售数据,包含“地区”、“城市”、“产品类别”、“销售额”和“订单数量”等字段。为了分析不同区域下各类产品的表现,我们需要按“地区”和“城市”进行分组,并对“销售额”求和、“订单数量”求平均值,同时保留原始数据的层次结构。这时,MultiIndex 就派上了用场。

首先,构建一个示例数据集:

python
import pandas as pd
import numpy as np

data = {
‘地区’: [‘华东’, ‘华东’, ‘华北’, ‘华北’, ‘华南’, ‘华南’],
‘城市’: [‘上海’, ‘杭州’, ‘北京’, ‘天津’, ‘广州’, ‘深圳’],
‘产品类别’: [‘手机’, ‘电脑’, ‘手机’, ‘电脑’, ‘手机’, ‘电脑’],
‘销售额’: [80000, 120000, 90000, 75000, 85000, 110000],
‘订单数量’: [400, 300, 450, 250, 420, 380]
}

df = pd.DataFrame(data)

接下来,设置多级索引。通过 set_index 方法将“地区”和“城市”设为行索引的两个层级:

python
df_indexed = df.set_index(['地区', '城市'])

此时,df_indexed 的索引就变成了两级结构:第一级是“地区”,第二级是“城市”。我们可以直观地看到每一层的嵌套关系,比如“华东”下面包含“上海”和“杭州”。

现在进入核心环节——分组聚合。虽然数据已有层级索引,但如果我们想按“地区”汇总所有城市的销售总额,同时计算每个“产品类别”的平均订单量,就需要结合 groupby 与 MultiIndex 的特性。

使用 groupby(level=0) 表示按第一级索引(即“地区”)分组:

python
result_by_region = df_indexed.groupby(level=0).agg({
'销售额': 'sum',
'订单数量': 'mean'
})

这会得到每个地区的总销售额和平均订单数。若要更精细地控制,比如同时按“地区”和“产品类别”分组,可以重置部分索引后重新组织:

python
df_reset = df_indexed.reset_index()
grouped = df_reset.groupby(['地区', '产品类别']).agg(
总销售额=('销售额', 'sum'),
平均订单数=('订单数量', 'mean')
).round(2)

这里使用了命名聚合(Named Aggregation),语法清晰且结果列名更具可读性。生成的结果本身也会自动形成 MultiIndex 列,便于后续筛选和展示。

值得一提的是,Pandas 允许我们在聚合后保持输出为 MultiIndex 结构。例如,当我们希望查看“每个地区-每座城市-每类产品”的组合统计时:

python
detailed_agg = df.groupby(['地区', '城市', '产品类别']).agg({
'销售额': ['sum', 'mean'],
'订单数量': 'sum'
})

这样的结果会产生一个带有双层列索引的 DataFrame,外层是字段名,内层是聚合方式。通过 detailed_agg.columns.get_level_values(0) 可以查看各层名称,也支持用 droplevelflatten 简化结构。

在实际应用中,常需对聚合结果进一步筛选。得益于 MultiIndex 的 .loc 支持元组切片,我们可以轻松提取特定子集:

python

获取华东地区的所有数据

eastdata = detailedagg.loc[‘华东’]

获取北京的所有信息

beijinginfo = detailedagg.xs(‘北京’, level=’城市’)

这种基于坐标的访问方式极大提升了多维数据的操作效率。

最后,合理使用 unstack()stack() 能够在不同维度间自由转换。例如将“产品类别”提至列级别,实现透视效果:

python
pivot_style = df_indexed.set_index('产品类别', append=True).unstack(fill_value=0)

综上所述,MultiIndex 不仅是一种数据组织形式,更是实现复杂分组聚合的强大载体。掌握其与 groupbyaggxs 等方法的配合使用,能让我们在面对高维业务数据时游刃有余,真正实现精细化分析。

picture loss