Skip to content

Instantly share code, notes, and snippets.

@hbuschme
Last active December 24, 2015 11:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hbuschme/6790387 to your computer and use it in GitHub Desktop.
Save hbuschme/6790387 to your computer and use it in GitHub Desktop.
Incrementally calculate sample mean, std, and var.
from __future__ import division
import numbers
import numpy as np
class IncrementalMeanStd(object):
'''Incremental calculation of sample mean, std, and var.
Based on http://www.johndcook.com/standard_deviation.html
'''
def __init__(self):
super(IncrementalMeanStd, self).__init__()
self._mk = 0 # mean_k
self._mk1 = 0 # mean_{k-1}
self._sk = 0 # s_k
self._k = 0 # k
def _update_mean(self, x):
'''Update sample mean given new sample x.'''
if self._k == 1:
return x
else:
return self._mk + (x - self._mk) / self._k
def _update_var(self, x):
'''Update sample var given new sample x.'''
if self._k == 1:
if isinstance(x, (np.number, numbers.Number)):
return 0
elif isinstance(x, np.ndarray):
return np.zeros_like(x)
else:
return self._sk + (x - self._mk1) * (x - self._mk)
def add(self, x):
'''Add a new sample and update calculation.'''
self._k += 1
self._mk1 = self._mk
self._mk = self._update_mean(x)
self._sk = self._update_var(x)
@property
def mean(self):
'''Sample mean.'''
return self._mk
@property
def std(self):
'''Sample std.'''
return np.sqrt(self.var)
@property
def var(self):
'''Sample var.'''
return self._sk / self._k
if __name__ == '__main__':
# Test
ims = IncrementalMeanStd()
l = range(10)
for x in l:
ims.add(x)
print(ims.mean, ims.std, ims.var)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment