20
20
import copy
21
21
import math
22
22
23
+
23
24
class StatCounter (object ):
24
-
25
+
25
26
def __init__ (self , values = []):
26
27
self .n = 0L # Running count of our values
27
28
self .mu = 0.0 # Running mean of our values
28
29
self .m2 = 0.0 # Running variance numerator (sum of (x - mean)^2)
29
30
self .maxValue = float ("-inf" )
30
31
self .minValue = float ("inf" )
31
-
32
+
32
33
for v in values :
33
34
self .merge (v )
34
-
35
+
35
36
# Add a value into this StatCounter, updating the internal statistics.
36
37
def merge (self , value ):
37
38
delta = value - self .mu
@@ -42,15 +43,15 @@ def merge(self, value):
42
43
self .maxValue = value
43
44
if self .minValue > value :
44
45
self .minValue = value
45
-
46
+
46
47
return self
47
48
48
49
# Merge another StatCounter into this one, adding up the internal statistics.
49
50
def mergeStats (self , other ):
50
51
if not isinstance (other , StatCounter ):
51
52
raise Exception ("Can only merge Statcounters!" )
52
53
53
- if other is self : # reference equality holds
54
+ if other is self : # reference equality holds
54
55
self .merge (copy .deepcopy (other )) # Avoid overwriting fields in a weird order
55
56
else :
56
57
if self .n == 0 :
@@ -59,19 +60,19 @@ def mergeStats(self, other):
59
60
self .n = other .n
60
61
self .maxValue = other .maxValue
61
62
self .minValue = other .minValue
62
-
63
- elif other .n != 0 :
63
+
64
+ elif other .n != 0 :
64
65
delta = other .mu - self .mu
65
66
if other .n * 10 < self .n :
66
67
self .mu = self .mu + (delta * other .n ) / (self .n + other .n )
67
68
elif self .n * 10 < other .n :
68
69
self .mu = other .mu - (delta * self .n ) / (self .n + other .n )
69
70
else :
70
71
self .mu = (self .mu * self .n + other .mu * other .n ) / (self .n + other .n )
71
-
72
+
72
73
self .maxValue = max (self .maxValue , other .maxValue )
73
74
self .minValue = min (self .minValue , other .minValue )
74
-
75
+
75
76
self .m2 += other .m2 + (delta * delta * self .n * other .n ) / (self .n + other .n )
76
77
self .n += other .n
77
78
return self
@@ -94,7 +95,7 @@ def min(self):
94
95
95
96
def max (self ):
96
97
return self .maxValue
97
-
98
+
98
99
# Return the variance of the values.
99
100
def variance (self ):
100
101
if self .n == 0 :
@@ -124,5 +125,5 @@ def sampleStdev(self):
124
125
return math .sqrt (self .sampleVariance ())
125
126
126
127
def __repr__ (self ):
127
- return "(count: %s, mean: %s, stdev: %s, max: %s, min: %s)" % ( self . count (), self . mean (), self . stdev (), self . max (), self . min ())
128
-
128
+ return "(count: %s, mean: %s, stdev: %s, max: %s, min: %s)" %
129
+ ( self . count (), self . mean (), self . stdev (), self . max (), self . min ())
0 commit comments