NumPy中的加权标准差
numpy.average()
这个函数可以让你在计算平均值的时候加上权重选项,也就是说你可以给不同的数据点设置不同的重要性。而 numpy.std()
这个函数用来计算标准差,但它没有类似的权重选项。有人在问,有没有什么办法可以解决这个问题?
7 个回答
45
还有一个选择:
np.sqrt(np.cov(values, aweights=weights))
55
在statsmodels
这个库里,有一个类可以方便地计算加权统计数据:statsmodels.stats.weightstats.DescrStatsW
。
假设你有这样一个数据集和权重:
import numpy as np
from statsmodels.stats.weightstats import DescrStatsW
array = np.array([1,2,1,2,1,2,1,3])
weights = np.ones_like(array)
weights[3] = 100
你需要先初始化这个类(注意,这里你需要传入一个修正因子,也就是自由度的delta值):
weighted_stats = DescrStatsW(array, weights=weights, ddof=0)
然后你就可以计算:
.mean
加权平均值:>>> weighted_stats.mean 1.97196261682243
.std
加权标准差:>>> weighted_stats.std 0.21434289609681711
.var
加权方差:>>> weighted_stats.var 0.045942877107170932
-
>>> weighted_stats.std_mean 0.020818822467555047
如果你对标准误差和标准差之间的关系感兴趣:标准误差(当
ddof == 0
时)是通过加权标准差除以权重总和减去1的平方根来计算的(这是GitHub上statsmodels
版本0.9的相关源代码):standard_error = standard_deviation / sqrt(sum(weights) - 1)
189
下面这个短小的“手动计算”怎么样呢?
def weighted_avg_and_std(values, weights):
"""
Return the weighted average and standard deviation.
They weights are in effect first normalized so that they
sum to 1 (and so they must not all be 0).
values, weights -- NumPy ndarrays with the same shape.
"""
average = numpy.average(values, weights=weights)
# Fast and numerically precise:
variance = numpy.average((values-average)**2, weights=weights)
return (average, math.sqrt(variance))