Skip to content

Commit 70f027d

Browse files
authored
bpo-40290: Add zscore() to statistics.NormalDist. (GH-19547)
1 parent 518835f commit 70f027d

File tree

4 files changed

+37
-0
lines changed

4 files changed

+37
-0
lines changed

Doc/library/statistics.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -696,6 +696,16 @@ of applications in statistics.
696696
Set *n* to 100 for percentiles which gives the 99 cuts points that
697697
separate the normal distribution into 100 equal sized groups.
698698

699+
.. method:: NormalDist.zscore(x)
700+
701+
Compute the
702+
`Standard Score <https://www.statisticshowto.com/probability-and-statistics/z-score/>`_
703+
describing *x* in terms of the number of standard deviations
704+
above or below the mean of the normal distribution:
705+
``(x - mean) / stdev``.
706+
707+
.. versionadded:: 3.9
708+
699709
Instances of :class:`NormalDist` support addition, subtraction,
700710
multiplication and division by a constant. These operations
701711
are used for translation and scaling. For example:

Lib/statistics.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -999,6 +999,17 @@ def overlap(self, other):
999999
x2 = (a - b) / dv
10001000
return 1.0 - (fabs(Y.cdf(x1) - X.cdf(x1)) + fabs(Y.cdf(x2) - X.cdf(x2)))
10011001

1002+
def zscore(self, x):
1003+
"""Compute the Standard Score. (x - mean) / stdev
1004+
1005+
Describes *x* in terms of the number of standard deviations
1006+
above or below the mean of the normal distribution.
1007+
"""
1008+
# https://www.statisticshowto.com/probability-and-statistics/z-score/
1009+
if not self._sigma:
1010+
raise StatisticsError('zscore() not defined when sigma is zero')
1011+
return (x - self._mu) / self._sigma
1012+
10021013
@property
10031014
def mean(self):
10041015
"Arithmetic mean of the normal distribution."

Lib/test/test_statistics.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2602,6 +2602,21 @@ def overlap_numeric(X, Y, *, steps=8_192, z=5):
26022602
with self.assertRaises(self.module.StatisticsError):
26032603
NormalDist(1, 0).overlap(X) # left operand sigma is zero
26042604

2605+
def test_zscore(self):
2606+
NormalDist = self.module.NormalDist
2607+
X = NormalDist(100, 15)
2608+
self.assertEqual(X.zscore(142), 2.8)
2609+
self.assertEqual(X.zscore(58), -2.8)
2610+
self.assertEqual(X.zscore(100), 0.0)
2611+
with self.assertRaises(TypeError):
2612+
X.zscore() # too few arguments
2613+
with self.assertRaises(TypeError):
2614+
X.zscore(1, 1) # too may arguments
2615+
with self.assertRaises(TypeError):
2616+
X.zscore(None) # non-numeric type
2617+
with self.assertRaises(self.module.StatisticsError):
2618+
NormalDist(1, 0).zscore(100) # sigma is zero
2619+
26052620
def test_properties(self):
26062621
X = self.module.NormalDist(100, 15)
26072622
self.assertEqual(X.mean, 100)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Added zscore() to statistics.NormalDist().

0 commit comments

Comments
 (0)