使用Python,假设我正在运行已知数量的项I
,并且能够计算处理每个t
所花费的时间,以及运行总计处理T
所花费的时间以及到目前为止处理的项目数c
。我正在计算飞行中的平均值A = T / c
,但这可能会因为单个项目需要花费相当长的时间来处理(几秒钟而不是几毫秒)。
我想展示正在运行的标准偏差。如何在不保留每个t
的记录的情况下执行此操作?
答案 0 :(得分:43)
正如Wikipedia article on the standard deviation中所述,跟踪以下三个总和就足够了:
s0 = sum(1 for x in samples)
s1 = sum(x for x in samples)
s2 = sum(x*x for x in samples)
随着新值的到来,这些总和很容易更新。标准偏差可以计算为
std_dev = math.sqrt((s0 * s2 - s1 * s1)/(s0 * (s0 - 1)))
请注意,如果样本是浮点数并且标准差与样本的平均值相比较小,则这种计算标准差的方法可能会受到数值条件的影响。如果您期望这种类型的样本,您应该采用Welford的方法(参见接受的答案)。
答案 1 :(得分:21)
import numpy as np
class OnlineVariance(object):
"""
Welford's algorithm computes the sample variance incrementally.
"""
def __init__(self, iterable=None, ddof=1):
self.ddof, self.n, self.mean, self.M2 = ddof, 0, 0.0, 0.0
if iterable is not None:
for datum in iterable:
self.include(datum)
def include(self, datum):
self.n += 1
self.delta = datum - self.mean
self.mean += self.delta / self.n
self.M2 += self.delta * (datum - self.mean)
@property
def variance(self):
return self.M2 / (self.n - self.ddof)
@property
def std(self):
return np.sqrt(self.variance)
更新每个新数据的差异:
N = 100
data = np.random.random(N)
ov = OnlineVariance(ddof=0)
for d in data:
ov.include(d)
std = ov.std
print(std)
根据numpy计算的标准差检查我们的结果:
assert np.allclose(std, data.std())
答案 2 :(得分:14)
我使用Welford's Method,这可以提供更准确的结果。此链接指向John D. Cook's overview。以下是其中的一个段落,总结了为什么它是首选方法:
这种计算方差的更好方法可以追溯到B. P. Welford在1962年发表的论文,并在Donald Knuth的计算机程序设计,第2卷,第232页,第3版中有所介绍。尽管这种解决方案已有数十年的历史,但还不足以让人知道。大多数人可能不知道计算样本方差可能很难,直到他们第一次计算标准偏差并获得负数的平方根的例外。