@@ -17,7 +17,18 @@ class Stat:
17
17
max : Optional [float ] = None
18
18
mean : Optional [float ] = None
19
19
variance : Optional [float ] = None
20
+ """This is the population variance, not the sample variance.
21
+
22
+ See https://towardsdatascience.com/variance-sample-vs-population-3ddbd29e498a
23
+ for details.
24
+ """
25
+
20
26
stddev : Optional [float ] = None
27
+ """This is the population standard deviation, not the sample standard deviation.
28
+
29
+ See https://towardsdatascience.com/variance-sample-vs-population-3ddbd29e498a
30
+ for details.
31
+ """
21
32
22
33
def add (self , x ) -> "Stat" :
23
34
# Skip Nones for statistic aggregation.
@@ -69,22 +80,17 @@ def process(x: Optional[float]) -> str:
69
80
else :
70
81
return "(0)"
71
82
72
- def _update_mean (self ):
73
- self . mean = self . sum / self . count if self .count else None
74
-
75
- def _update_variance ( self ):
76
- self . _update_mean ()
77
- if self .mean is None :
78
- return None
83
+ def _update_mean_variance_stddev (self ):
84
+ if self .count == 0 :
85
+ # No stats with no elements.
86
+ return
87
+ # Update mean
88
+ self .mean = self . sum / self . count
89
+ # Update variance
79
90
pvariance = self .sum_squared / self .count - self .mean ** 2
80
91
self .variance = 0 if pvariance < 0 else pvariance
81
-
82
- def _update_stddev (self ):
83
- self ._update_variance ()
84
- self .stddev = math .sqrt (self .variance ) if self .variance is not None else None
85
-
86
- def _update_mean_variance_stddev (self ):
87
- self ._update_stddev ()
92
+ # Update stddev
93
+ self .stddev = math .sqrt (self .variance )
88
94
89
95
def take_mean (self ):
90
96
"""Return a version of the stat that only has the mean."""
0 commit comments