多级索引DataFrame:Lambda函数实现均值的均值原理解析
两级索引DataFrame的两种均值计算方法解析
问题场景
我有一个包含两级索引(index1为主索引,index2为次索引)的DataFrame,已经能用「均值的均值」方法计算每个主索引对应的整体均值,同时发现用lambda+apply的方法能得到相同结果,但不清楚后者的执行逻辑,希望得到详细解析。
示例代码
import numpy as np import pandas as pd arrays = [ np.array(["bar", "bar", "baz", "baz", "foo", "foo", "qux", "qux"]), np.array(["one", "two", "one", "two", "one", "two", "one", "two"]), ] df = pd.DataFrame(np.random.randn(8, 4), index=arrays) df.index.names = ['index1', 'index2'] # 方法1:使用lambda+apply计算 mean1 = df.groupby(level='index1').apply(lambda cormat: cormat.values.mean()) # 方法2:均值的均值 mean2 = df.groupby(level=['index1']).mean().mean(axis=1) print(mean1, mean2)
方法2(均值的均值)执行逻辑
- 第一步:
df.groupby(level='index1').mean()
按主索引index1分组,对每个分组内的所有列分别计算均值。这一步会生成一个新的DataFrame,索引为index1的所有唯一值,列名和原DataFrame一致,每个单元格的值是对应主索引组下该列的行均值。 - 第二步:
.mean(axis=1)
对第一步得到的DataFrame按行计算均值,也就是把每个主索引对应的各列均值再做一次平均,最终得到每个主索引组下所有数据的整体均值。
方法1(lambda+apply)执行逻辑
这是重点解析的部分,执行流程分三步:
- 分组阶段:
df.groupby(level='index1')
把原DataFrame按index1的唯一值(bar、baz、foo、qux)分成4个独立的子DataFrame,每个子DataFrame包含对应index1的所有行数据(比如bar组包含index2为one和two的2行4列数据)。 - 逐组执行lambda函数:
apply(lambda cormat: cormat.values.mean())
对每个分组后的子DataFrame(参数cormat就是当前处理的子DataFrame)执行lambda逻辑:cormat.values:将子DataFrame转换为numpy数组,比如bar组的数组形状为(2,4),包含8个数值;.mean():调用numpy数组的均值方法,默认对数组内所有元素求平均(不管维度),也就是直接计算该主索引组下所有数据的整体均值。
- 结果整合:
apply会自动把每个分组计算得到的均值,整理成一个以index1为索引的Series,也就是最终的mean1。
两种方法的等价性
两种方法本质上都是计算每个主索引组内所有数据的整体均值,数学上完全等价:
- 方法2是先按列求均值,再对列均值求行均值;
- 方法1是直接对组内所有元素求均值。
由于每个index1组内的元素数量相同(都是2行×4列=8个值),两种计算方式的结果完全一致。
内容的提问来源于stack exchange,提问作者HnV
相关产品推荐
相关产品推荐

