From 08be4c602a082ffe9735740d971f5f760dd4fc58 Mon Sep 17 00:00:00 2001 From: Marc Garcia Date: Mon, 10 Dec 2018 17:23:15 +0000 Subject: [PATCH] DEPR: Deprecating .clip_lower and .clip_upper (#24203) --- doc/source/whatsnew/v0.24.0.rst | 1 + pandas/core/generic.py | 41 ++++++++++++++------------- pandas/tests/frame/test_analytics.py | 15 ++++++---- pandas/tests/series/test_analytics.py | 20 +++++++++---- 4 files changed, 47 insertions(+), 30 deletions(-) diff --git a/doc/source/whatsnew/v0.24.0.rst b/doc/source/whatsnew/v0.24.0.rst index a18c26f911f1d8..fdfd6c8c26a521 100644 --- a/doc/source/whatsnew/v0.24.0.rst +++ b/doc/source/whatsnew/v0.24.0.rst @@ -1115,6 +1115,7 @@ Deprecations - Creating a :class:`TimedeltaIndex` or :class:`DatetimeIndex` by passing range arguments `start`, `end`, and `periods` is deprecated in favor of :func:`timedelta_range` and :func:`date_range` (:issue:`23919`) - Passing a string alias like ``'datetime64[ns, UTC]'`` as the `unit` parameter to :class:`DatetimeTZDtype` is deprecated. Use :class:`DatetimeTZDtype.construct_from_string` instead (:issue:`23990`). - In :meth:`Series.where` with Categorical data, providing an ``other`` that is not present in the categories is deprecated. Convert the categorical to a different dtype or add the ``other`` to the categories first (:issue:`24077`). +- :meth:`Series.clip_lower`, :meth:`Series.clip_upper`, :meth:`DataFrame.clip_lower` and :meth:`DataFrame.clip_upper` are deprecated and will be removed in a future version. Use ``Series.clip(lower=threshold)``, ``Series.clip(upper=threshold)`` and the equivalent ``DataFrame`` methods (:issue:`24203`) .. _whatsnew_0240.deprecations.datetimelike_int_ops: diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 9eb3eb37a01cc0..ba50b971b6ff98 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -7204,11 +7204,6 @@ def clip(self, lower=None, upper=None, axis=None, inplace=False, Same type as calling object with the values outside the clip boundaries replaced - See Also - -------- - clip_lower : Clip values below specified threshold(s). - clip_upper : Clip values above specified threshold(s). - Examples -------- >>> data = {'col_0': [9, -3, 0, -1, 5], 'col_1': [-2, -7, 6, 8, -5]} @@ -7281,11 +7276,13 @@ def clip(self, lower=None, upper=None, axis=None, inplace=False, result = self if lower is not None: - result = result.clip_lower(lower, axis, inplace=inplace) + result = result._clip_with_one_bound(lower, method=self.ge, + axis=axis, inplace=inplace) if upper is not None: if inplace: result = self - result = result.clip_upper(upper, axis, inplace=inplace) + result = result._clip_with_one_bound(upper, method=self.le, + axis=axis, inplace=inplace) return result @@ -7293,6 +7290,9 @@ def clip_upper(self, threshold, axis=None, inplace=False): """ Trim values above a given threshold. + .. deprecated:: 0.24.0 + Use clip(upper=threshold) instead. + Elements above the `threshold` will be changed to match the `threshold` value(s). Threshold can be a single value or an array, in the latter case it performs the truncation element-wise. @@ -7319,18 +7319,15 @@ def clip_upper(self, threshold, axis=None, inplace=False): Returns ------- - clipped + Series or DataFrame Original data with values trimmed. See Also -------- - DataFrame.clip : General purpose method to trim DataFrame values to - given threshold(s). - DataFrame.clip_lower : Trim DataFrame values below given - threshold(s). Series.clip : General purpose method to trim Series values to given threshold(s). - Series.clip_lower : Trim Series values below given threshold(s). + DataFrame.clip : General purpose method to trim DataFrame values to + given threshold(s). Examples -------- @@ -7363,6 +7360,9 @@ def clip_upper(self, threshold, axis=None, inplace=False): 4 1 dtype: int64 """ + warnings.warn('clip_upper(threshold) is deprecated, ' + 'use clip(upper=threshold) instead', + FutureWarning, stacklevel=2) return self._clip_with_one_bound(threshold, method=self.le, axis=axis, inplace=inplace) @@ -7370,6 +7370,9 @@ def clip_lower(self, threshold, axis=None, inplace=False): """ Trim values below a given threshold. + .. deprecated:: 0.24.0 + Use clip(lower=threshold) instead. + Elements below the `threshold` will be changed to match the `threshold` value(s). Threshold can be a single value or an array, in the latter case it performs the truncation element-wise. @@ -7397,18 +7400,15 @@ def clip_lower(self, threshold, axis=None, inplace=False): Returns ------- - clipped + Series or DataFrame Original data with values trimmed. See Also -------- - DataFrame.clip : General purpose method to trim DataFrame values to - given threshold(s). - DataFrame.clip_upper : Trim DataFrame values above given - threshold(s). Series.clip : General purpose method to trim Series values to given threshold(s). - Series.clip_upper : Trim Series values above given threshold(s). + DataFrame.clip : General purpose method to trim DataFrame values to + given threshold(s). Examples -------- @@ -7476,6 +7476,9 @@ def clip_lower(self, threshold, axis=None, inplace=False): 1 4 5 2 5 6 """ + warnings.warn('clip_lower(threshold) is deprecated, ' + 'use clip(lower=threshold) instead', + FutureWarning, stacklevel=2) return self._clip_with_one_bound(threshold, method=self.ge, axis=axis, inplace=inplace) diff --git a/pandas/tests/frame/test_analytics.py b/pandas/tests/frame/test_analytics.py index 6c30f3fb02fb0e..88262220015c72 100644 --- a/pandas/tests/frame/test_analytics.py +++ b/pandas/tests/frame/test_analytics.py @@ -1841,10 +1841,12 @@ def test_clip(self, float_frame): median = float_frame.median().median() original = float_frame.copy() - capped = float_frame.clip_upper(median) + with tm.assert_produces_warning(FutureWarning): + capped = float_frame.clip_upper(median) assert not (capped.values > median).any() - floored = float_frame.clip_lower(median) + with tm.assert_produces_warning(FutureWarning): + floored = float_frame.clip_lower(median) assert not (floored.values < median).any() double = float_frame.clip(upper=median, lower=median) @@ -1858,11 +1860,13 @@ def test_inplace_clip(self, float_frame): median = float_frame.median().median() frame_copy = float_frame.copy() - frame_copy.clip_upper(median, inplace=True) + with tm.assert_produces_warning(FutureWarning): + frame_copy.clip_upper(median, inplace=True) assert not (frame_copy.values > median).any() frame_copy = float_frame.copy() - frame_copy.clip_lower(median, inplace=True) + with tm.assert_produces_warning(FutureWarning): + frame_copy.clip_lower(median, inplace=True) assert not (frame_copy.values < median).any() frame_copy = float_frame.copy() @@ -2263,7 +2267,8 @@ def test_series_broadcasting(self): s_nan = Series([np.nan, np.nan, 1]) with tm.assert_produces_warning(None): - df_nan.clip_lower(s, axis=0) + with tm.assert_produces_warning(FutureWarning): + df_nan.clip_lower(s, axis=0) for op in ['lt', 'le', 'gt', 'ge', 'eq', 'ne']: getattr(df, op)(s_nan, axis=0) diff --git a/pandas/tests/series/test_analytics.py b/pandas/tests/series/test_analytics.py index a9c8e855cd3249..81d60aba44b0f6 100644 --- a/pandas/tests/series/test_analytics.py +++ b/pandas/tests/series/test_analytics.py @@ -924,8 +924,10 @@ def test_matmul(self): def test_clip(self, datetime_series): val = datetime_series.median() - assert datetime_series.clip_lower(val).min() == val - assert datetime_series.clip_upper(val).max() == val + with tm.assert_produces_warning(FutureWarning): + assert datetime_series.clip_lower(val).min() == val + with tm.assert_produces_warning(FutureWarning): + assert datetime_series.clip_upper(val).max() == val assert datetime_series.clip(lower=val).min() == val assert datetime_series.clip(upper=val).max() == val @@ -943,8 +945,10 @@ def test_clip_types_and_nulls(self): for s in sers: thresh = s[2] - lower = s.clip_lower(thresh) - upper = s.clip_upper(thresh) + with tm.assert_produces_warning(FutureWarning): + lower = s.clip_lower(thresh) + with tm.assert_produces_warning(FutureWarning): + upper = s.clip_upper(thresh) assert lower[notna(lower)].min() == thresh assert upper[notna(upper)].max() == thresh assert list(isna(s)) == list(isna(lower)) @@ -971,8 +975,12 @@ def test_clip_against_series(self): s = Series([1.0, 1.0, 4.0]) threshold = Series([1.0, 2.0, 3.0]) - assert_series_equal(s.clip_lower(threshold), Series([1.0, 2.0, 4.0])) - assert_series_equal(s.clip_upper(threshold), Series([1.0, 1.0, 3.0])) + with tm.assert_produces_warning(FutureWarning): + assert_series_equal(s.clip_lower(threshold), + Series([1.0, 2.0, 4.0])) + with tm.assert_produces_warning(FutureWarning): + assert_series_equal(s.clip_upper(threshold), + Series([1.0, 1.0, 3.0])) lower = Series([1.0, 2.0, 3.0]) upper = Series([1.5, 2.5, 3.5])