有时候在处理流式数据的时候,需要实时更新数据的统计值,如平均值和方差,如果通过传统求解方差或者平均值时,每到达一个新的数据就需要遍历来求解。在数据量比较少的时候,通过遍历和递推求解的时间消耗和空间消耗并不是很明显,但是在大数据或者流式数据的应用场景下, O ( n ) O(n) O(n)和 O ( 1 ) O(1) O(1)的时间复杂度以及空间复杂度的区别还是很明显的。
均值公式:
A
n
=
1
n
∑
i
=
1
n
X
i
A_{n} = \frac{1}{n}\sum^{n}_{i=1}X_{i}
An=n1i=1∑nXi
均值递推公式:
A
n
=
A
n
−
1
+
(
X
n
−
A
n
−
1
)
n
A_{n} = A_{n-1} + \frac{(X_{n} - A_{n-1})}{n}
An=An−1+n(Xn−An−1)
方差公式:
V
n
=
1
n
∑
i
=
1
n
(
X
i
−
A
n
)
V_{n} = \frac{1}{n}\sum_{i=1}^{n}(X_{i} - A_{n})
Vn=n1i=1∑n(Xi−An)
方差递推公式:
V
n
=
n
−
1
n
2
(
X
n
−
A
n
−
1
)
2
+
n
−
1
n
V
n
−
1
V_{n} = \frac{n-1}{n^{2}}(X_{n} - A_{n-1})^{2} + \frac{n-1}{n}V_{n-1}
Vn=n2n−1(Xn−An−1)2+nn−1Vn−1
均值递推公式可以参考:https://blog.csdn.net/u014485485/article/details/77679669
方差递推公式可以参考:https://blog.csdn.net/wuqinlong/article/details/78432574
python代码:
import numpy as np
class CalMeanVar():
def __init__(self):
self.count = 0
self.A = 0
self.A_ = 0
self.V = 0
def cal(self, data):
self.count += 1
if self.count == 1:
self.A_ = data
self.A = data
return
self.A_ = self.A
self.A = self.A + (data - self.A) / self.count
self.V = (self.count - 1) / self.count ** 2 * (data - self.A_)**2 + (self.count - 1)/self.count * self.V
if __name__ == '__main__':
data = np.linspace(1,5, 5)
print(data)
print(data.mean())
print(data.var())
cmv = CalMeanVar()
for i in range(len(data)):
cmv.cal(data[i])
print(cmv.A)
print(cmv.V)