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