悠悠楠杉
网站页面
正文:
在数据分析中,分组加权平均是常见需求。例如,电商需要按品类计算商品价格的销量加权平均值,或金融领域按行业计算股票的市值加权收益率。Pandas的groupby虽强大,但直接实现加权平均需巧妙处理权重与数据的关联。此时,闭包(Closure)能优雅地解决上下文变量传递问题。
假设有销售数据DataFrame,需按category分组计算价格的quantity加权平均值:
import pandas as pd
data = {
'category': ['A', 'A', 'B', 'B', 'B'],
'price': [10, 20, 30, 40, 50],
'quantity': [100, 50, 80, 70, 60]
}
df = pd.DataFrame(data)
闭包能捕获外部函数的变量,避免全局变量污染。以下是核心实现:
def weighted_avg_factory(weight_col):
def weighted_avg(group):
return (group['price'] * group[weight_col]).sum() / group[weight_col].sum()
return weighted_avg
# 使用闭包
result = df.groupby('category').apply(weighted_avg_factory('quantity'))
print(result)
关键点解析:
1. weighted_avg_factory接收权重列名(如quantity),返回内层函数weighted_avg;
2. 内层函数通过闭包自动访问外部函数的weight_col参数,无需额外传递;
3. groupby.apply调用时,闭包维持了权重列的上下文。
若数据量大,可结合numba加速或使用agg方法:
# 方法2:agg + lambda(适合简单逻辑)
result = df.groupby('category').agg(
weighted_avg=('price', lambda x: (x * df.loc[x.index, 'quantity']).sum() / df.loc[x.index, 'quantity'].sum())
)
quantity为revenue);通过闭包,Pandas分组加权平均变得高效且易于维护。此模式同样适用于其他需要上下文保存的复杂分组计算场景。