summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaymond Hettinger <rhettinger@users.noreply.github.com>2020-04-16 17:25:14 (GMT)
committerGitHub <noreply@github.com>2020-04-16 17:25:14 (GMT)
commit70f027dd22d6522b777d10c250f951e5e416b93a (patch)
treeb0208da206e983459af5eb714dc38ed026c51153
parent518835f3354d6672e61c9f52348c1e4a2533ea00 (diff)
downloadcpython-70f027dd22d6522b777d10c250f951e5e416b93a.zip
cpython-70f027dd22d6522b777d10c250f951e5e416b93a.tar.gz
cpython-70f027dd22d6522b777d10c250f951e5e416b93a.tar.bz2
bpo-40290: Add zscore() to statistics.NormalDist. (GH-19547)
-rw-r--r--Doc/library/statistics.rst10
-rw-r--r--Lib/statistics.py11
-rw-r--r--Lib/test/test_statistics.py15
-rw-r--r--Misc/NEWS.d/next/Library/2020-04-15-16-43-48.bpo-40290.eqCMGJ.rst1
4 files changed, 37 insertions, 0 deletions
diff --git a/Doc/library/statistics.rst b/Doc/library/statistics.rst
index 026f4aa..38a499a 100644
--- a/Doc/library/statistics.rst
+++ b/Doc/library/statistics.rst
@@ -696,6 +696,16 @@ of applications in statistics.
Set *n* to 100 for percentiles which gives the 99 cuts points that
separate the normal distribution into 100 equal sized groups.
+ .. method:: NormalDist.zscore(x)
+
+ Compute the
+ `Standard Score <https://www.statisticshowto.com/probability-and-statistics/z-score/>`_
+ describing *x* in terms of the number of standard deviations
+ above or below the mean of the normal distribution:
+ ``(x - mean) / stdev``.
+
+ .. versionadded:: 3.9
+
Instances of :class:`NormalDist` support addition, subtraction,
multiplication and division by a constant. These operations
are used for translation and scaling. For example:
diff --git a/Lib/statistics.py b/Lib/statistics.py
index 1e95c0b..9beafb3 100644
--- a/Lib/statistics.py
+++ b/Lib/statistics.py
@@ -999,6 +999,17 @@ class NormalDist:
x2 = (a - b) / dv
return 1.0 - (fabs(Y.cdf(x1) - X.cdf(x1)) + fabs(Y.cdf(x2) - X.cdf(x2)))
+ def zscore(self, x):
+ """Compute the Standard Score. (x - mean) / stdev
+
+ Describes *x* in terms of the number of standard deviations
+ above or below the mean of the normal distribution.
+ """
+ # https://www.statisticshowto.com/probability-and-statistics/z-score/
+ if not self._sigma:
+ raise StatisticsError('zscore() not defined when sigma is zero')
+ return (x - self._mu) / self._sigma
+
@property
def mean(self):
"Arithmetic mean of the normal distribution."
diff --git a/Lib/test/test_statistics.py b/Lib/test/test_statistics.py
index a9a427b..0e46a71 100644
--- a/Lib/test/test_statistics.py
+++ b/Lib/test/test_statistics.py
@@ -2602,6 +2602,21 @@ class TestNormalDist:
with self.assertRaises(self.module.StatisticsError):
NormalDist(1, 0).overlap(X) # left operand sigma is zero
+ def test_zscore(self):
+ NormalDist = self.module.NormalDist
+ X = NormalDist(100, 15)
+ self.assertEqual(X.zscore(142), 2.8)
+ self.assertEqual(X.zscore(58), -2.8)
+ self.assertEqual(X.zscore(100), 0.0)
+ with self.assertRaises(TypeError):
+ X.zscore() # too few arguments
+ with self.assertRaises(TypeError):
+ X.zscore(1, 1) # too may arguments
+ with self.assertRaises(TypeError):
+ X.zscore(None) # non-numeric type
+ with self.assertRaises(self.module.StatisticsError):
+ NormalDist(1, 0).zscore(100) # sigma is zero
+
def test_properties(self):
X = self.module.NormalDist(100, 15)
self.assertEqual(X.mean, 100)
diff --git a/Misc/NEWS.d/next/Library/2020-04-15-16-43-48.bpo-40290.eqCMGJ.rst b/Misc/NEWS.d/next/Library/2020-04-15-16-43-48.bpo-40290.eqCMGJ.rst
new file mode 100644
index 0000000..a930cee
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2020-04-15-16-43-48.bpo-40290.eqCMGJ.rst
@@ -0,0 +1 @@
+Added zscore() to statistics.NormalDist().