]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-40290: Add zscore() to statistics.NormalDist. (GH-19547)
authorRaymond Hettinger <rhettinger@users.noreply.github.com>
Thu, 16 Apr 2020 17:25:14 +0000 (10:25 -0700)
committerGitHub <noreply@github.com>
Thu, 16 Apr 2020 17:25:14 +0000 (10:25 -0700)
Doc/library/statistics.rst
Lib/statistics.py
Lib/test/test_statistics.py
Misc/NEWS.d/next/Library/2020-04-15-16-43-48.bpo-40290.eqCMGJ.rst [new file with mode: 0644]

index 026f4aa462d3d73d671422900ef5224f3a062639..38a499ab37e890d377ae9f1a29da9470356ba524 100644 (file)
@@ -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:
index 1e95c0b6639f1703a56bd34ef673b4740505259f..9beafb341b3ad141784d8b433117e02e9ccf2ff2 100644 (file)
@@ -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."
index a9a427bc8d972ac09a0761be2d99dd1a861b6f53..0e46a7119f0efcf3f5314e1209da61abf59ced91 100644 (file)
@@ -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 (file)
index 0000000..a930cee
--- /dev/null
@@ -0,0 +1 @@
+Added zscore() to statistics.NormalDist().