如何优雅地标准化Pandas GroupBy分组结果并计算子组均值与总体均值的偏差
优雅计算Pandas子组均值与总体均值的偏差
这确实是个很实用的需求,而且Pandas提供了非常简洁的实现方式,完全不用繁琐的loc或者apply嵌套。我们可以直接借助groupby的聚合功能,一次性完成子组均值计算和偏差统计,下面是具体的实现方案:
第一步:先获取总体均值
首先我们可以提前算出整个数据集的总体均值,后续所有子组的偏差都基于这个值计算:
import numpy as np import pandas as pd from pprint import pprint # 你的原始数据准备代码 d = np.array([[1,4],[1,1],[0,1],[1,1]]) m = d.mean(axis=1) p = pd.DataFrame(m,index='A1,A2,B1,B2'.split(','),columns=['Obs']) # 计算总体均值 overall_mean = p['Obs'].mean() # 结果是1.25,和你示例中的一致
第二步:分组计算均值与偏差
借助groupby的agg方法,我们可以在一次聚合操作中同时得到子组均值和与总体均值的偏差:
按A/B分组(索引首字符)
# 按索引首字符分组,同时计算Obs均值和Dev偏差 result_ab = p.groupby(lambda idx: idx[0])['Obs'].agg( Obs='mean', Dev=lambda x: x.mean() - overall_mean ) pprint(result_ab)
输出结果:
Obs Dev A 1.75 0.5 B 0.75 -0.5
按1/2分组(索引第二个字符)
# 按索引第二个字符分组,同样计算均值和偏差 result_12 = p.groupby(lambda idx: idx[1])['Obs'].agg( Obs='mean', Dev=lambda x: x.mean() - overall_mean ) pprint(result_12)
输出结果:
Obs Dev 1 1.50 0.25 2 1.00 -0.25
为什么这个方案更优雅?
- 避免了多次数据操作:不需要先分组计算均值,再手动合并偏差列,一次
agg操作完成所有需求 - 代码可读性高:通过命名参数直接指定列名和对应的计算逻辑,逻辑清晰
- 充分利用Pandas的原生优化:
groupby和agg都是Pandas高度优化的方法,性能比手动循环或apply更好
内容的提问来源于stack exchange,提问作者Rense Lange
相关产品推荐
相关产品推荐

