diff --git a/doc/source/whatsnew/v0.16.0.txt b/doc/source/whatsnew/v0.16.0.txt index 21b1ddea0e9da..528c32d84e898 100644 --- a/doc/source/whatsnew/v0.16.0.txt +++ b/doc/source/whatsnew/v0.16.0.txt @@ -141,3 +141,4 @@ Bug Fixes - Bug in read_csv when using skiprows on a file with CR line endings with the c engine. (:issue:`9079`) - isnull now detects NaT in PeriodIndex (:issue:`9129`) - Bug in groupby ``.nth()`` with a multiple column groupby (:issue:`8979`) +- Fixed division by zero error for ``Series.kurt()`` when all values are equal (:issue:`9197`) diff --git a/pandas/core/nanops.py b/pandas/core/nanops.py index 9703dba40a18a..b3d8f2b67ffab 100644 --- a/pandas/core/nanops.py +++ b/pandas/core/nanops.py @@ -514,17 +514,21 @@ def nankurt(values, axis=None, skipna=True): C = _zero_out_fperr(C) D = _zero_out_fperr(D) + if not isinstance(B, np.ndarray): + # if B is a scalar, check these corner cases first before doing division + if count < 4: + return np.nan + if B == 0: + return 0 + result = (((count * count - 1.) * D / (B * B) - 3 * ((count - 1.) ** 2)) / ((count - 2.) * (count - 3.))) + if isinstance(result, np.ndarray): result = np.where(B == 0, 0, result) result[count < 4] = np.nan - return result - else: - result = 0 if B == 0 else result - if count < 4: - return np.nan - return result + + return result @disallow('M8','m8') diff --git a/pandas/tests/test_series.py b/pandas/tests/test_series.py index 93cebd034b4df..9b072e2f62968 100644 --- a/pandas/tests/test_series.py +++ b/pandas/tests/test_series.py @@ -2212,6 +2212,18 @@ def test_skew(self): alt = lambda x: skew(x, bias=False) self._check_stat_op('skew', alt) + # test corner cases, skew() returns NaN unless there's at least 3 values + min_N = 3 + for i in range(1, min_N + 1): + s = Series(np.ones(i)) + df = DataFrame(np.ones((i, i))) + if i < min_N: + self.assertTrue(np.isnan(s.skew())) + self.assertTrue(np.isnan(df.skew()).all()) + else: + self.assertEqual(0, s.skew()) + self.assertTrue((df.skew() == 0).all()) + def test_kurt(self): tm._skip_if_no_scipy() @@ -2226,6 +2238,18 @@ def test_kurt(self): s = Series(np.random.randn(6), index=index) self.assertAlmostEqual(s.kurt(), s.kurt(level=0)['bar']) + # test corner cases, kurt() returns NaN unless there's at least 4 values + min_N = 4 + for i in range(1, min_N + 1): + s = Series(np.ones(i)) + df = DataFrame(np.ones((i, i))) + if i < min_N: + self.assertTrue(np.isnan(s.kurt())) + self.assertTrue(np.isnan(df.kurt()).all()) + else: + self.assertEqual(0, s.kurt()) + self.assertTrue((df.kurt() == 0).all()) + def test_argsort(self): self._check_accum_op('argsort') argsorted = self.ts.argsort()