adaptive_stats.quickstats

  1#!/usr/bin/env python
  2
  3import math
  4
  5class QuickStats:
  6    """
  7    Computationally stable and efficient basic descriptive statistics.
  8    This class uses Kalman Filter updating to tally sample mean and sum
  9    of squares, along with min, max, and sample size. Sample variance,
 10    standard deviation and standard error are calculated on demand.
 11    """
 12
 13    def __init__(self):
 14        """Initialize state vars in a new QuickStats object using reset()."""
 15        self.reset()
 16
 17    def reset(self):
 18        """
 19        Reset all state vars to initial values.
 20
 21          ssd = n = 0
 22          sample_mean = sample_variance = NaN
 23          min = infinity
 24          max = -infinity
 25
 26        Returns:
 27            self (QuickStats) - to facilitate method chaining
 28        """
 29        self.__ssd = 0.0
 30        self.__n = 0
 31        self.__sample_mean = math.nan
 32        self.__max = -math.inf
 33        self.__min = math.inf
 34        return self
 35
 36    def new_obs(self, datum):
 37        """
 38        Update the sample size, sample mean, sum of squares, min, and max given
 39        a new observation. All but the sample size are maintained as floating point.
 40
 41        Parameters:
 42            datum (numeric) : the new observation
 43        Returns:
 44            self (QuickStats) - to facilitate method chaining
 45        Raises:
 46            RuntimeError if datum is non-numeric
 47        """
 48        x = float(datum)
 49        if x > self.__max:
 50            self.__max = x
 51        if x < self.__min:
 52            self.__min = x
 53        if self.__n > 0:
 54            delta = x - self.__sample_mean
 55            self.__n += 1
 56            self.__sample_mean += delta / self.__n
 57            self.__ssd += delta * (x - self.__sample_mean)
 58        else:
 59            self.__sample_mean = x
 60            self.__n = 1
 61        return self
 62
 63    def add_all(self, iterable_collection):
 64        """
 65        Update the statistics with all elements of an enumerable set.
 66
 67        Parameters:
 68            iterable_collection (Iterable[numeric]) : a collection of new observations.
 69        Returns:
 70            self (QuickStats) - to facilitate method chaining
 71        """
 72        for x in iterable_collection:
 73            self.new_obs(x)
 74        return self
 75
 76    add_list = add_all
 77    add_set = add_all
 78
 79    @property
 80    def sample_variance(self):
 81        """
 82        Calculates the unbiased sample variance on demand (divisor is n-1).
 83
 84        Returns:
 85            sample variance (float) of the data, or NaN if this is a
 86            new or just-reset QuickStats object.
 87        """
 88        return (self.__ssd / (self.__n - 1)) if self.__n > 1 else math.nan
 89
 90    var = sample_variance
 91
 92    @property
 93    def mle_sample_variance(self):
 94        """
 95        Calculates the MLE sample variance on demand (divisor is n).
 96
 97        Returns:
 98            MLE sample variance (float) of the data, or NaN if this is a
 99            new or just-reset QuickStats object.
100        """
101        return (self.__ssd / self.__n) if self.__n > 1 else math.nan
102
103    mle_var = mle_sample_variance
104
105    @property
106    def standard_deviation(self):
107        """
108        Calculates the square root of the unbiased sample variance on demand.
109
110        Returns:
111            sample standard deviation (float) of the data, or NaN if this is a
112            new or just-reset QuickStats object.
113        """
114        return math.sqrt(self.sample_variance) if self.n > 1 else math.nan
115
116    s = standard_deviation
117    std_dev = standard_deviation
118
119    @property
120    def mle_standard_deviation(self):
121        """
122        Calculates the square root of the MLE sample variance on demand.
123
124        Returns:
125            MLE standard deviation (float) of the data, or NaN if this is a
126            new or just-reset QuickStats object.
127        """
128        return math.sqrt(self.mle_sample_variance) if self.n > 1 else math.nan
129
130    mle_s = mle_standard_deviation
131    mle_std_dev = mle_standard_deviation
132
133    @property
134    def standard_error(self):
135        """
136        Calculates sqrt(sample_variance / n) on demand.
137
138        Returns:
139            unbiased sample standard error (float) of the data, or NaN if this is a
140            new or just-reset QuickStats object.
141        """
142        return math.sqrt(self.sample_variance / self.__n) if self.n > 1 else math.nan
143
144    std_err = standard_error
145
146    @property
147    def mle_standard_error(self):
148        """
149        Calculates sqrt(mle_sample_variance / n) on demand.
150
151        Returns:
152            sample standard error (float) of the data based on MLE,
153            or NaN if this is a new or just-reset QuickStats object.
154        """
155        return math.sqrt(self.mle_sample_variance / self.__n) if self.n > 1 else math.nan
156
157    mle_std_err = mle_standard_error
158
159    def loss(self, *, target=0.0):
160        """
161        Estimates quadratic loss (a la Taguchi) relative to a specified
162        target value.
163
164        Parameters:
165            target (float) : the designated target value for the loss function.
166        Returns:
167            quadratic loss (float) calculated for the data, or NaN if this is a
168            new or just-reset QuickStats object.
169        """
170        return (
171            math.nan
172            if self.n < 2
173            else (self.avg - target) ** 2 + self.var
174        )
175
176    # getters for n, sample_mean, min, max, ssd
177
178    @property
179    def n(self):
180        """current sample size"""
181        return self.__n
182
183    @property
184    def sample_mean(self):
185        """current average of the data"""
186        return self.__sample_mean
187
188    @property
189    def min(self):
190        """current minimum of the data"""
191        return self.__min
192
193    @property
194    def max(self):
195        """current maximum of the data"""
196        return self.__max
197
198    @property
199    def ssd(self):
200        """current sum of squared deviations from the avergage of the data"""
201        return self.__ssd
202
203    average = sample_mean
204    avg = sample_mean
205    sample_size = n
206    sum_squared_deviations = ssd
class QuickStats:
  6class QuickStats:
  7    """
  8    Computationally stable and efficient basic descriptive statistics.
  9    This class uses Kalman Filter updating to tally sample mean and sum
 10    of squares, along with min, max, and sample size. Sample variance,
 11    standard deviation and standard error are calculated on demand.
 12    """
 13
 14    def __init__(self):
 15        """Initialize state vars in a new QuickStats object using reset()."""
 16        self.reset()
 17
 18    def reset(self):
 19        """
 20        Reset all state vars to initial values.
 21
 22          ssd = n = 0
 23          sample_mean = sample_variance = NaN
 24          min = infinity
 25          max = -infinity
 26
 27        Returns:
 28            self (QuickStats) - to facilitate method chaining
 29        """
 30        self.__ssd = 0.0
 31        self.__n = 0
 32        self.__sample_mean = math.nan
 33        self.__max = -math.inf
 34        self.__min = math.inf
 35        return self
 36
 37    def new_obs(self, datum):
 38        """
 39        Update the sample size, sample mean, sum of squares, min, and max given
 40        a new observation. All but the sample size are maintained as floating point.
 41
 42        Parameters:
 43            datum (numeric) : the new observation
 44        Returns:
 45            self (QuickStats) - to facilitate method chaining
 46        Raises:
 47            RuntimeError if datum is non-numeric
 48        """
 49        x = float(datum)
 50        if x > self.__max:
 51            self.__max = x
 52        if x < self.__min:
 53            self.__min = x
 54        if self.__n > 0:
 55            delta = x - self.__sample_mean
 56            self.__n += 1
 57            self.__sample_mean += delta / self.__n
 58            self.__ssd += delta * (x - self.__sample_mean)
 59        else:
 60            self.__sample_mean = x
 61            self.__n = 1
 62        return self
 63
 64    def add_all(self, iterable_collection):
 65        """
 66        Update the statistics with all elements of an enumerable set.
 67
 68        Parameters:
 69            iterable_collection (Iterable[numeric]) : a collection of new observations.
 70        Returns:
 71            self (QuickStats) - to facilitate method chaining
 72        """
 73        for x in iterable_collection:
 74            self.new_obs(x)
 75        return self
 76
 77    add_list = add_all
 78    add_set = add_all
 79
 80    @property
 81    def sample_variance(self):
 82        """
 83        Calculates the unbiased sample variance on demand (divisor is n-1).
 84
 85        Returns:
 86            sample variance (float) of the data, or NaN if this is a
 87            new or just-reset QuickStats object.
 88        """
 89        return (self.__ssd / (self.__n - 1)) if self.__n > 1 else math.nan
 90
 91    var = sample_variance
 92
 93    @property
 94    def mle_sample_variance(self):
 95        """
 96        Calculates the MLE sample variance on demand (divisor is n).
 97
 98        Returns:
 99            MLE sample variance (float) of the data, or NaN if this is a
100            new or just-reset QuickStats object.
101        """
102        return (self.__ssd / self.__n) if self.__n > 1 else math.nan
103
104    mle_var = mle_sample_variance
105
106    @property
107    def standard_deviation(self):
108        """
109        Calculates the square root of the unbiased sample variance on demand.
110
111        Returns:
112            sample standard deviation (float) of the data, or NaN if this is a
113            new or just-reset QuickStats object.
114        """
115        return math.sqrt(self.sample_variance) if self.n > 1 else math.nan
116
117    s = standard_deviation
118    std_dev = standard_deviation
119
120    @property
121    def mle_standard_deviation(self):
122        """
123        Calculates the square root of the MLE sample variance on demand.
124
125        Returns:
126            MLE standard deviation (float) of the data, or NaN if this is a
127            new or just-reset QuickStats object.
128        """
129        return math.sqrt(self.mle_sample_variance) if self.n > 1 else math.nan
130
131    mle_s = mle_standard_deviation
132    mle_std_dev = mle_standard_deviation
133
134    @property
135    def standard_error(self):
136        """
137        Calculates sqrt(sample_variance / n) on demand.
138
139        Returns:
140            unbiased sample standard error (float) of the data, or NaN if this is a
141            new or just-reset QuickStats object.
142        """
143        return math.sqrt(self.sample_variance / self.__n) if self.n > 1 else math.nan
144
145    std_err = standard_error
146
147    @property
148    def mle_standard_error(self):
149        """
150        Calculates sqrt(mle_sample_variance / n) on demand.
151
152        Returns:
153            sample standard error (float) of the data based on MLE,
154            or NaN if this is a new or just-reset QuickStats object.
155        """
156        return math.sqrt(self.mle_sample_variance / self.__n) if self.n > 1 else math.nan
157
158    mle_std_err = mle_standard_error
159
160    def loss(self, *, target=0.0):
161        """
162        Estimates quadratic loss (a la Taguchi) relative to a specified
163        target value.
164
165        Parameters:
166            target (float) : the designated target value for the loss function.
167        Returns:
168            quadratic loss (float) calculated for the data, or NaN if this is a
169            new or just-reset QuickStats object.
170        """
171        return (
172            math.nan
173            if self.n < 2
174            else (self.avg - target) ** 2 + self.var
175        )
176
177    # getters for n, sample_mean, min, max, ssd
178
179    @property
180    def n(self):
181        """current sample size"""
182        return self.__n
183
184    @property
185    def sample_mean(self):
186        """current average of the data"""
187        return self.__sample_mean
188
189    @property
190    def min(self):
191        """current minimum of the data"""
192        return self.__min
193
194    @property
195    def max(self):
196        """current maximum of the data"""
197        return self.__max
198
199    @property
200    def ssd(self):
201        """current sum of squared deviations from the avergage of the data"""
202        return self.__ssd
203
204    average = sample_mean
205    avg = sample_mean
206    sample_size = n
207    sum_squared_deviations = ssd

Computationally stable and efficient basic descriptive statistics. This class uses Kalman Filter updating to tally sample mean and sum of squares, along with min, max, and sample size. Sample variance, standard deviation and standard error are calculated on demand.

QuickStats()
14    def __init__(self):
15        """Initialize state vars in a new QuickStats object using reset()."""
16        self.reset()

Initialize state vars in a new QuickStats object using reset().

def reset(self):
18    def reset(self):
19        """
20        Reset all state vars to initial values.
21
22          ssd = n = 0
23          sample_mean = sample_variance = NaN
24          min = infinity
25          max = -infinity
26
27        Returns:
28            self (QuickStats) - to facilitate method chaining
29        """
30        self.__ssd = 0.0
31        self.__n = 0
32        self.__sample_mean = math.nan
33        self.__max = -math.inf
34        self.__min = math.inf
35        return self

Reset all state vars to initial values.

ssd = n = 0 sample_mean = sample_variance = NaN min = infinity max = -infinity

Returns: self (QuickStats) - to facilitate method chaining

def new_obs(self, datum):
37    def new_obs(self, datum):
38        """
39        Update the sample size, sample mean, sum of squares, min, and max given
40        a new observation. All but the sample size are maintained as floating point.
41
42        Parameters:
43            datum (numeric) : the new observation
44        Returns:
45            self (QuickStats) - to facilitate method chaining
46        Raises:
47            RuntimeError if datum is non-numeric
48        """
49        x = float(datum)
50        if x > self.__max:
51            self.__max = x
52        if x < self.__min:
53            self.__min = x
54        if self.__n > 0:
55            delta = x - self.__sample_mean
56            self.__n += 1
57            self.__sample_mean += delta / self.__n
58            self.__ssd += delta * (x - self.__sample_mean)
59        else:
60            self.__sample_mean = x
61            self.__n = 1
62        return self

Update the sample size, sample mean, sum of squares, min, and max given a new observation. All but the sample size are maintained as floating point.

Parameters: datum (numeric) : the new observation Returns: self (QuickStats) - to facilitate method chaining Raises: RuntimeError if datum is non-numeric

def add_all(self, iterable_collection):
64    def add_all(self, iterable_collection):
65        """
66        Update the statistics with all elements of an enumerable set.
67
68        Parameters:
69            iterable_collection (Iterable[numeric]) : a collection of new observations.
70        Returns:
71            self (QuickStats) - to facilitate method chaining
72        """
73        for x in iterable_collection:
74            self.new_obs(x)
75        return self

Update the statistics with all elements of an enumerable set.

Parameters: iterable_collection (Iterable[numeric]) : a collection of new observations. Returns: self (QuickStats) - to facilitate method chaining

def add_list(self, iterable_collection):
64    def add_all(self, iterable_collection):
65        """
66        Update the statistics with all elements of an enumerable set.
67
68        Parameters:
69            iterable_collection (Iterable[numeric]) : a collection of new observations.
70        Returns:
71            self (QuickStats) - to facilitate method chaining
72        """
73        for x in iterable_collection:
74            self.new_obs(x)
75        return self

Update the statistics with all elements of an enumerable set.

Parameters: iterable_collection (Iterable[numeric]) : a collection of new observations. Returns: self (QuickStats) - to facilitate method chaining

def add_set(self, iterable_collection):
64    def add_all(self, iterable_collection):
65        """
66        Update the statistics with all elements of an enumerable set.
67
68        Parameters:
69            iterable_collection (Iterable[numeric]) : a collection of new observations.
70        Returns:
71            self (QuickStats) - to facilitate method chaining
72        """
73        for x in iterable_collection:
74            self.new_obs(x)
75        return self

Update the statistics with all elements of an enumerable set.

Parameters: iterable_collection (Iterable[numeric]) : a collection of new observations. Returns: self (QuickStats) - to facilitate method chaining

sample_variance
80    @property
81    def sample_variance(self):
82        """
83        Calculates the unbiased sample variance on demand (divisor is n-1).
84
85        Returns:
86            sample variance (float) of the data, or NaN if this is a
87            new or just-reset QuickStats object.
88        """
89        return (self.__ssd / (self.__n - 1)) if self.__n > 1 else math.nan

Calculates the unbiased sample variance on demand (divisor is n-1).

Returns: sample variance (float) of the data, or NaN if this is a new or just-reset QuickStats object.

var
80    @property
81    def sample_variance(self):
82        """
83        Calculates the unbiased sample variance on demand (divisor is n-1).
84
85        Returns:
86            sample variance (float) of the data, or NaN if this is a
87            new or just-reset QuickStats object.
88        """
89        return (self.__ssd / (self.__n - 1)) if self.__n > 1 else math.nan

Calculates the unbiased sample variance on demand (divisor is n-1).

Returns: sample variance (float) of the data, or NaN if this is a new or just-reset QuickStats object.

mle_sample_variance
 93    @property
 94    def mle_sample_variance(self):
 95        """
 96        Calculates the MLE sample variance on demand (divisor is n).
 97
 98        Returns:
 99            MLE sample variance (float) of the data, or NaN if this is a
100            new or just-reset QuickStats object.
101        """
102        return (self.__ssd / self.__n) if self.__n > 1 else math.nan

Calculates the MLE sample variance on demand (divisor is n).

Returns: MLE sample variance (float) of the data, or NaN if this is a new or just-reset QuickStats object.

mle_var
 93    @property
 94    def mle_sample_variance(self):
 95        """
 96        Calculates the MLE sample variance on demand (divisor is n).
 97
 98        Returns:
 99            MLE sample variance (float) of the data, or NaN if this is a
100            new or just-reset QuickStats object.
101        """
102        return (self.__ssd / self.__n) if self.__n > 1 else math.nan

Calculates the MLE sample variance on demand (divisor is n).

Returns: MLE sample variance (float) of the data, or NaN if this is a new or just-reset QuickStats object.

standard_deviation
106    @property
107    def standard_deviation(self):
108        """
109        Calculates the square root of the unbiased sample variance on demand.
110
111        Returns:
112            sample standard deviation (float) of the data, or NaN if this is a
113            new or just-reset QuickStats object.
114        """
115        return math.sqrt(self.sample_variance) if self.n > 1 else math.nan

Calculates the square root of the unbiased sample variance on demand.

Returns: sample standard deviation (float) of the data, or NaN if this is a new or just-reset QuickStats object.

s
106    @property
107    def standard_deviation(self):
108        """
109        Calculates the square root of the unbiased sample variance on demand.
110
111        Returns:
112            sample standard deviation (float) of the data, or NaN if this is a
113            new or just-reset QuickStats object.
114        """
115        return math.sqrt(self.sample_variance) if self.n > 1 else math.nan

Calculates the square root of the unbiased sample variance on demand.

Returns: sample standard deviation (float) of the data, or NaN if this is a new or just-reset QuickStats object.

std_dev
106    @property
107    def standard_deviation(self):
108        """
109        Calculates the square root of the unbiased sample variance on demand.
110
111        Returns:
112            sample standard deviation (float) of the data, or NaN if this is a
113            new or just-reset QuickStats object.
114        """
115        return math.sqrt(self.sample_variance) if self.n > 1 else math.nan

Calculates the square root of the unbiased sample variance on demand.

Returns: sample standard deviation (float) of the data, or NaN if this is a new or just-reset QuickStats object.

mle_standard_deviation
120    @property
121    def mle_standard_deviation(self):
122        """
123        Calculates the square root of the MLE sample variance on demand.
124
125        Returns:
126            MLE standard deviation (float) of the data, or NaN if this is a
127            new or just-reset QuickStats object.
128        """
129        return math.sqrt(self.mle_sample_variance) if self.n > 1 else math.nan

Calculates the square root of the MLE sample variance on demand.

Returns: MLE standard deviation (float) of the data, or NaN if this is a new or just-reset QuickStats object.

mle_s
120    @property
121    def mle_standard_deviation(self):
122        """
123        Calculates the square root of the MLE sample variance on demand.
124
125        Returns:
126            MLE standard deviation (float) of the data, or NaN if this is a
127            new or just-reset QuickStats object.
128        """
129        return math.sqrt(self.mle_sample_variance) if self.n > 1 else math.nan

Calculates the square root of the MLE sample variance on demand.

Returns: MLE standard deviation (float) of the data, or NaN if this is a new or just-reset QuickStats object.

mle_std_dev
120    @property
121    def mle_standard_deviation(self):
122        """
123        Calculates the square root of the MLE sample variance on demand.
124
125        Returns:
126            MLE standard deviation (float) of the data, or NaN if this is a
127            new or just-reset QuickStats object.
128        """
129        return math.sqrt(self.mle_sample_variance) if self.n > 1 else math.nan

Calculates the square root of the MLE sample variance on demand.

Returns: MLE standard deviation (float) of the data, or NaN if this is a new or just-reset QuickStats object.

standard_error
134    @property
135    def standard_error(self):
136        """
137        Calculates sqrt(sample_variance / n) on demand.
138
139        Returns:
140            unbiased sample standard error (float) of the data, or NaN if this is a
141            new or just-reset QuickStats object.
142        """
143        return math.sqrt(self.sample_variance / self.__n) if self.n > 1 else math.nan

Calculates sqrt(sample_variance / n) on demand.

Returns: unbiased sample standard error (float) of the data, or NaN if this is a new or just-reset QuickStats object.

std_err
134    @property
135    def standard_error(self):
136        """
137        Calculates sqrt(sample_variance / n) on demand.
138
139        Returns:
140            unbiased sample standard error (float) of the data, or NaN if this is a
141            new or just-reset QuickStats object.
142        """
143        return math.sqrt(self.sample_variance / self.__n) if self.n > 1 else math.nan

Calculates sqrt(sample_variance / n) on demand.

Returns: unbiased sample standard error (float) of the data, or NaN if this is a new or just-reset QuickStats object.

mle_standard_error
147    @property
148    def mle_standard_error(self):
149        """
150        Calculates sqrt(mle_sample_variance / n) on demand.
151
152        Returns:
153            sample standard error (float) of the data based on MLE,
154            or NaN if this is a new or just-reset QuickStats object.
155        """
156        return math.sqrt(self.mle_sample_variance / self.__n) if self.n > 1 else math.nan

Calculates sqrt(mle_sample_variance / n) on demand.

Returns: sample standard error (float) of the data based on MLE, or NaN if this is a new or just-reset QuickStats object.

mle_std_err
147    @property
148    def mle_standard_error(self):
149        """
150        Calculates sqrt(mle_sample_variance / n) on demand.
151
152        Returns:
153            sample standard error (float) of the data based on MLE,
154            or NaN if this is a new or just-reset QuickStats object.
155        """
156        return math.sqrt(self.mle_sample_variance / self.__n) if self.n > 1 else math.nan

Calculates sqrt(mle_sample_variance / n) on demand.

Returns: sample standard error (float) of the data based on MLE, or NaN if this is a new or just-reset QuickStats object.

def loss(self, *, target=0.0):
160    def loss(self, *, target=0.0):
161        """
162        Estimates quadratic loss (a la Taguchi) relative to a specified
163        target value.
164
165        Parameters:
166            target (float) : the designated target value for the loss function.
167        Returns:
168            quadratic loss (float) calculated for the data, or NaN if this is a
169            new or just-reset QuickStats object.
170        """
171        return (
172            math.nan
173            if self.n < 2
174            else (self.avg - target) ** 2 + self.var
175        )

Estimates quadratic loss (a la Taguchi) relative to a specified target value.

Parameters: target (float) : the designated target value for the loss function. Returns: quadratic loss (float) calculated for the data, or NaN if this is a new or just-reset QuickStats object.

n
179    @property
180    def n(self):
181        """current sample size"""
182        return self.__n

current sample size

sample_mean
184    @property
185    def sample_mean(self):
186        """current average of the data"""
187        return self.__sample_mean

current average of the data

min
189    @property
190    def min(self):
191        """current minimum of the data"""
192        return self.__min

current minimum of the data

max
194    @property
195    def max(self):
196        """current maximum of the data"""
197        return self.__max

current maximum of the data

ssd
199    @property
200    def ssd(self):
201        """current sum of squared deviations from the avergage of the data"""
202        return self.__ssd

current sum of squared deviations from the avergage of the data

average
184    @property
185    def sample_mean(self):
186        """current average of the data"""
187        return self.__sample_mean

current average of the data

avg
184    @property
185    def sample_mean(self):
186        """current average of the data"""
187        return self.__sample_mean

current average of the data

sample_size
179    @property
180    def n(self):
181        """current sample size"""
182        return self.__n

current sample size

sum_squared_deviations
199    @property
200    def ssd(self):
201        """current sum of squared deviations from the avergage of the data"""
202        return self.__ssd

current sum of squared deviations from the avergage of the data