bpo-36018: Add properties for mean and stdev (GH-12022)

Responding to suggestions on the tracker and some off-line suggestions.

Davin suggested that english named accessors instead of greek letters would result in more intelligible user code. Steven suggested that the parameters still need to be *mu* and *theta* which are used elsewhere (and I noted those parameter names are used in linked-to resources). 

Michael suggested proving-out the API by seeing whether it generalized to *Lognormal*.  I did so and found that Lognormal distribution parameters *mu* and *sigma*  do not represent the mean and standard deviation of the lognormal distribution (instead, they are for the underlying regular normal distribution).

Putting these ideas together, we have NormalDist parameterized by *mu* and *sigma* but offering English named properties for accessors.  That gives lets us match other API that access mu and sigma, it matches the external resources on the topic, gives us clear english names in user code. The API extends nicely to LogNormal where the parameters and the summary statistic accessors are not the same.


https://bugs.python.org/issue36018
This commit is contained in:
Raymond Hettinger 2019-02-24 11:44:55 -08:00 committed by Miss Islington (bot)
parent a875ea58b2
commit 9e456bc70e
3 changed files with 26 additions and 6 deletions

View File

@ -488,13 +488,17 @@ of applications in statistics, including simulations and hypothesis testing.
If *sigma* is negative, raises :exc:`StatisticsError`. If *sigma* is negative, raises :exc:`StatisticsError`.
.. attribute:: mu .. attribute:: mean
The mean of a normal distribution. A read-only property representing the `arithmetic mean
<https://en.wikipedia.org/wiki/Arithmetic_mean>`_ of a normal
distribution.
.. attribute:: sigma .. attribute:: stdev
The standard deviation of a normal distribution. A read-only property representing the `standard deviation
<https://en.wikipedia.org/wiki/Standard_deviation>`_ of a normal
distribution.
.. attribute:: variance .. attribute:: variance
@ -566,8 +570,8 @@ of applications in statistics, including simulations and hypothesis testing.
>>> birth_weights = NormalDist.from_samples([2.5, 3.1, 2.1, 2.4, 2.7, 3.5]) >>> birth_weights = NormalDist.from_samples([2.5, 3.1, 2.1, 2.4, 2.7, 3.5])
>>> drug_effects = NormalDist(0.4, 0.15) >>> drug_effects = NormalDist(0.4, 0.15)
>>> combined = birth_weights + drug_effects >>> combined = birth_weights + drug_effects
>>> f'mu={combined.mu :.1f} sigma={combined.sigma :.1f}' >>> f'mean: {combined.mean :.1f} standard deviation: {combined.stdev :.1f}'
'mu=3.1 sigma=0.5' 'mean: 3.1 standard deviation: 0.5'
.. versionadded:: 3.8 .. versionadded:: 3.8

View File

@ -740,6 +740,16 @@ class NormalDist:
raise StatisticsError('cdf() not defined when sigma is zero') raise StatisticsError('cdf() not defined when sigma is zero')
return 0.5 * (1.0 + erf((x - self.mu) / (self.sigma * sqrt(2.0)))) return 0.5 * (1.0 + erf((x - self.mu) / (self.sigma * sqrt(2.0))))
@property
def mean(self):
'Arithmetic mean of the normal distribution'
return self.mu
@property
def stdev(self):
'Standard deviation of the normal distribution'
return self.sigma
@property @property
def variance(self): def variance(self):
'Square of the standard deviation' 'Square of the standard deviation'

View File

@ -2128,6 +2128,12 @@ class TestNormalDist(unittest.TestCase):
with self.assertRaises(statistics.StatisticsError): with self.assertRaises(statistics.StatisticsError):
Y.cdf(90) Y.cdf(90)
def test_properties(self):
X = statistics.NormalDist(100, 15)
self.assertEqual(X.mean, 100)
self.assertEqual(X.stdev, 15)
self.assertEqual(X.variance, 225)
def test_unary_operations(self): def test_unary_operations(self):
NormalDist = statistics.NormalDist NormalDist = statistics.NormalDist
X = NormalDist(100, 12) X = NormalDist(100, 12)