From e49c07827c036ecb2b3e185e5facf22aee73fad9 Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Wed, 27 Nov 2019 19:50:45 -0800 Subject: [PATCH 1/2] DEPR: categorical.take allow_fill default --- pandas/core/arrays/categorical.py | 23 ++++++++++--------- pandas/tests/arrays/categorical/test_algos.py | 13 ++++++++--- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/pandas/core/arrays/categorical.py b/pandas/core/arrays/categorical.py index 6cc3f660fb425..40672226e7f78 100644 --- a/pandas/core/arrays/categorical.py +++ b/pandas/core/arrays/categorical.py @@ -1829,7 +1829,7 @@ def fillna(self, value=None, method=None, limit=None): return self._constructor(codes, dtype=self.dtype, fastpath=True) - def take_nd(self, indexer, allow_fill=None, fill_value=None): + def take(self, indexer, allow_fill: bool = False, fill_value=None): """ Take elements from the Categorical. @@ -1838,7 +1838,7 @@ def take_nd(self, indexer, allow_fill=None, fill_value=None): indexer : sequence of int The indices in `self` to take. The meaning of negative values in `indexer` depends on the value of `allow_fill`. - allow_fill : bool, default None + allow_fill : bool, default False How to handle negative values in `indexer`. * False: negative values in `indices` indicate positional indices @@ -1849,11 +1849,9 @@ def take_nd(self, indexer, allow_fill=None, fill_value=None): (the default). These values are set to `fill_value`. Any other other negative values raise a ``ValueError``. - .. versionchanged:: 0.23.0 + .. versionchanged:: 1.0.0 - Deprecated the default value of `allow_fill`. The deprecated - default is ``True``. In the future, this will change to - ``False``. + Default value changed from ``True`` to ``False``. fill_value : object The value to use for `indices` that are missing (-1), when @@ -1903,10 +1901,6 @@ def take_nd(self, indexer, allow_fill=None, fill_value=None): will raise a ``TypeError``. """ indexer = np.asarray(indexer, dtype=np.intp) - if allow_fill is None: - if (indexer < 0).any(): - warn(_take_msg, FutureWarning, stacklevel=2) - allow_fill = True dtype = self.dtype @@ -1927,7 +1921,14 @@ def take_nd(self, indexer, allow_fill=None, fill_value=None): result = type(self).from_codes(codes, dtype=dtype) return result - take = take_nd + def take_nd(self, indexer, allow_fill: bool = False, fill_value=None): + # GH#27745 deprecate alias that other EAs dont have + warn( + "Categorical.take_nd is deprecated, use Categorical.take instead", + FutureWarning, + stacklevel=2, + ) + return self.take(indexer, allow_fill=allow_fill, fill_value=fill_value) def __len__(self) -> int: """ diff --git a/pandas/tests/arrays/categorical/test_algos.py b/pandas/tests/arrays/categorical/test_algos.py index e076015c5f61d..dce3c4e4d5e98 100644 --- a/pandas/tests/arrays/categorical/test_algos.py +++ b/pandas/tests/arrays/categorical/test_algos.py @@ -89,10 +89,12 @@ def test_isin_empty(empty): class TestTake: # https://github.com/pandas-dev/pandas/issues/20664 - def test_take_warns(self): + def test_take_default_allow_fill(self): cat = pd.Categorical(["a", "b"]) - with tm.assert_produces_warning(FutureWarning): - cat.take([0, -1]) + with tm.assert_produces_warning(None): + result = cat.take([0, -1]) + + assert result.equals(cat) def test_take_positive_no_warning(self): cat = pd.Categorical(["a", "b"]) @@ -158,3 +160,8 @@ def test_take_fill_value_new_raises(self): xpr = r"'fill_value' \('d'\) is not in this Categorical's categories." with pytest.raises(TypeError, match=xpr): cat.take([0, 1, -1], fill_value="d", allow_fill=True) + + def test_take_nd_deprecated(self): + cat = pd.Categorical(["a", "b", "c"]) + with tm.assert_produces_warning(FutureWarning): + cat.take_nd([0, 1]) From 587eaa82ea9035ea852b56efc68006b3a81181f6 Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Wed, 27 Nov 2019 19:55:12 -0800 Subject: [PATCH 2/2] whatsnew, remove take_msg --- doc/source/whatsnew/v1.0.0.rst | 3 ++- pandas/core/arrays/categorical.py | 13 ------------- 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/doc/source/whatsnew/v1.0.0.rst b/doc/source/whatsnew/v1.0.0.rst index 8a9b9db140409..839cc92f3c13e 100644 --- a/doc/source/whatsnew/v1.0.0.rst +++ b/doc/source/whatsnew/v1.0.0.rst @@ -365,6 +365,7 @@ Deprecations is equivalent to ``arr[idx.get_loc(idx_val)] = val``, which should be used instead (:issue:`28621`). - :func:`is_extension_type` is deprecated, :func:`is_extension_array_dtype` should be used instead (:issue:`29457`) - :func:`eval` keyword argument "truediv" is deprecated and will be removed in a future version (:issue:`29812`) +- :meth:`Categorical.take_nd` is deprecated, use :meth:`Categorical.take` instead (:issue:`27745`) .. _whatsnew_1000.prior_deprecations: @@ -453,10 +454,10 @@ or ``matplotlib.Axes.plot``. See :ref:`plotting.formatters` for more. - In :func:`concat` the default value for ``sort`` has been changed from ``None`` to ``False`` (:issue:`20613`) - Removed previously deprecated "raise_conflict" argument from :meth:`DataFrame.update`, use "errors" instead (:issue:`23585`) - Removed previously deprecated keyword "n" from :meth:`DatetimeIndex.shift`, :meth:`TimedeltaIndex.shift`, :meth:`PeriodIndex.shift`, use "periods" instead (:issue:`22458`) +- Changed the default ``fill_value`` in :meth:`Categorical.take` from ``True`` to ``False`` (:issue:`20841`) - Changed the default value for the `raw` argument in :func:`Series.rolling().apply() `, :func:`DataFrame.rolling().apply() `, - :func:`Series.expanding().apply() `, and :func:`DataFrame.expanding().apply() ` to ``False`` (:issue:`20584`) - Removed previously deprecated :attr:`Timestamp.weekday_name`, :attr:`DatetimeIndex.weekday_name`, and :attr:`Series.dt.weekday_name` (:issue:`18164`) -- .. _whatsnew_1000.performance: diff --git a/pandas/core/arrays/categorical.py b/pandas/core/arrays/categorical.py index 40672226e7f78..cd1f5ea8a175b 100644 --- a/pandas/core/arrays/categorical.py +++ b/pandas/core/arrays/categorical.py @@ -1,6 +1,5 @@ import operator from shutil import get_terminal_size -import textwrap from typing import Type, Union, cast from warnings import warn @@ -59,18 +58,6 @@ from .base import ExtensionArray, _extension_array_shared_docs, try_cast_to_ea -_take_msg = textwrap.dedent( - """\ - Interpreting negative values in 'indexer' as missing values. - In the future, this will change to meaning positional indices - from the right. - - Use 'allow_fill=True' to retain the previous behavior and silence this - warning. - - Use 'allow_fill=False' to accept the new behavior.""" -) - def _cat_compare_op(op): opname = f"__{op.__name__}__"