From ae29378df5a2558ebe3cc5b3505f5907c028f73b Mon Sep 17 00:00:00 2001 From: ajcr Date: Tue, 22 Sep 2015 21:20:06 +0100 Subject: [PATCH] ENH: make Series.ptp ignore NaN values (GH11163) --- doc/source/whatsnew/v0.17.0.txt | 1 + doc/source/whatsnew/v0.17.1.txt | 1 + pandas/core/generic.py | 11 +++++++++++ pandas/core/series.py | 3 --- pandas/tests/test_series.py | 25 +++++++++++++++++++++++++ 5 files changed, 38 insertions(+), 3 deletions(-) diff --git a/doc/source/whatsnew/v0.17.0.txt b/doc/source/whatsnew/v0.17.0.txt index 0b2bb0b5a475c..9f943fa68e639 100644 --- a/doc/source/whatsnew/v0.17.0.txt +++ b/doc/source/whatsnew/v0.17.0.txt @@ -527,6 +527,7 @@ Other enhancements - ``pd.read_csv`` is now able to infer compression type for files read from AWS S3 storage (:issue:`11070`, :issue:`11074`). + .. _whatsnew_0170.api: .. _whatsnew_0170.api_breaking: diff --git a/doc/source/whatsnew/v0.17.1.txt b/doc/source/whatsnew/v0.17.1.txt index 3d10566e47075..67c3ef39a8cb5 100755 --- a/doc/source/whatsnew/v0.17.1.txt +++ b/doc/source/whatsnew/v0.17.1.txt @@ -60,6 +60,7 @@ API changes - ``Series.sort_index()`` now correctly handles the ``inplace`` option (:issue:`11402`) - ``DataFrame.itertuples()`` now returns ``namedtuple`` objects, when possible. (:issue:`11269`) +- ``Series.ptp`` will now ignore missing values by default (:issue:`11163`) .. _whatsnew_0171.deprecations: diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 605c95bfb0ba2..4cc1cac65243c 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -4701,6 +4701,17 @@ def stat_func(self, axis=None, skipna=None, level=None, want the *index* of the minimum, use ``idxmin``. This is the equivalent of the ``numpy.ndarray`` method ``argmin``.""", nanops.nanmin) + if cls.__name__ == 'Series': + def nanptp(values, axis=0, skipna=True): + nmax = nanops.nanmax(values, axis, skipna) + nmin = nanops.nanmin(values, axis, skipna) + return nmax - nmin + + cls.ptp = _make_stat_function('ptp', """ +Returns the difference between the maximum value and the minimum +value in the object. This is the equivalent of the ``numpy.ndarray`` +method ``ptp``.""", nanptp) + def _make_logical_function(name, desc, f): @Substitution(outname=name, desc=desc) diff --git a/pandas/core/series.py b/pandas/core/series.py index 5106225cdd3c9..9b498bb969cbc 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -1277,9 +1277,6 @@ def multi(values, qs): return self._maybe_box(lambda values: multi(values, q), dropna=True) - def ptp(self, axis=None, out=None): - return _values_from_object(self).ptp(axis, out) - def corr(self, other, method='pearson', min_periods=None): """ diff --git a/pandas/tests/test_series.py b/pandas/tests/test_series.py index 1c8cbac60e7c7..f8f065f3371ab 100644 --- a/pandas/tests/test_series.py +++ b/pandas/tests/test_series.py @@ -5949,6 +5949,31 @@ def test_ptp(self): ser = Series(arr) self.assertEqual(np.ptp(ser), np.ptp(arr)) + # GH11163 + s = Series([3, 5, np.nan, -3, 10]) + self.assertEqual(s.ptp(), 13) + self.assertTrue(pd.isnull(s.ptp(skipna=False))) + + mi = pd.MultiIndex.from_product([['a','b'], [1,2,3]]) + s = pd.Series([1, np.nan, 7, 3, 5, np.nan], index=mi) + + expected = pd.Series([6, 2], index=['a', 'b'], dtype=np.float64) + self.assert_series_equal(s.ptp(level=0), expected) + + expected = pd.Series([np.nan, np.nan], index=['a', 'b']) + self.assert_series_equal(s.ptp(level=0, skipna=False), expected) + + with self.assertRaises(ValueError): + s.ptp(axis=1) + + s = pd.Series(['a', 'b', 'c', 'd', 'e']) + with self.assertRaises(TypeError): + s.ptp() + + with self.assertRaises(NotImplementedError): + s.ptp(numeric_only=True) + + def test_asof(self): # array or list or dates N = 50