1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 import copy
21 import math
22
24
26 self.n = 0L
27 self.mu = 0.0
28 self.m2 = 0.0
29 self.maxValue = float("-inf")
30 self.minValue = float("inf")
31
32 for v in values:
33 self.merge(v)
34
35
37 delta = value - self.mu
38 self.n += 1
39 self.mu += delta / self.n
40 self.m2 += delta * (value - self.mu)
41 if self.maxValue < value:
42 self.maxValue = value
43 if self.minValue > value:
44 self.minValue = value
45
46 return self
47
48
50 if not isinstance(other, StatCounter):
51 raise Exception("Can only merge Statcounters!")
52
53 if other is self:
54 self.merge(copy.deepcopy(other))
55 else:
56 if self.n == 0:
57 self.mu = other.mu
58 self.m2 = other.m2
59 self.n = other.n
60 self.maxValue = other.maxValue
61 self.minValue = other.minValue
62
63 elif other.n != 0:
64 delta = other.mu - self.mu
65 if other.n * 10 < self.n:
66 self.mu = self.mu + (delta * other.n) / (self.n + other.n)
67 elif self.n * 10 < other.n:
68 self.mu = other.mu - (delta * self.n) / (self.n + other.n)
69 else:
70 self.mu = (self.mu * self.n + other.mu * other.n) / (self.n + other.n)
71
72 self.maxValue = max(self.maxValue, other.maxValue)
73 self.minValue = min(self.minValue, other.minValue)
74
75 self.m2 += other.m2 + (delta * delta * self.n * other.n) / (self.n + other.n)
76 self.n += other.n
77 return self
78
79
81 return copy.deepcopy(self)
82
85
88
90 return self.n * self.mu
91
94
97
98
100 if self.n == 0:
101 return float('nan')
102 else:
103 return self.m2 / self.n
104
105
106
107
108
110 if self.n <= 1:
111 return float('nan')
112 else:
113 return self.m2 / (self.n - 1)
114
115
118
119
120
121
122
125
127 return "(count: %s, mean: %s, stdev: %s, max: %s, min: %s)" % (self.count(), self.mean(), self.stdev(), self.max(), self.min())
128