diff --git a/doc/source/whatsnew/v1.0.0.rst b/doc/source/whatsnew/v1.0.0.rst index b5f8e8ca4a126..052d58f1487fe 100644 --- a/doc/source/whatsnew/v1.0.0.rst +++ b/doc/source/whatsnew/v1.0.0.rst @@ -418,6 +418,7 @@ or ``matplotlib.Axes.plot``. See :ref:`plotting.formatters` for more. - Removed :meth:`DataFrame.as_blocks`, :meth:`Series.as_blocks`, `DataFrame.blocks`, :meth:`Series.blocks` (:issue:`17656`) - :meth:`pandas.Series.str.cat` now defaults to aligning ``others``, using ``join='left'`` (:issue:`27611`) - :meth:`pandas.Series.str.cat` does not accept list-likes *within* list-likes anymore (:issue:`27611`) +- :meth:`Series.where` with ``Categorical`` dtype (or :meth:`DataFrame.where` with ``Categorical`` column) no longer allows setting new categories (:issue:`24114`) - :func:`core.internals.blocks.make_block` no longer accepts the "fastpath" keyword(:issue:`19265`) - :meth:`Block.make_block_same_class` no longer accepts the "dtype" keyword(:issue:`19434`) - Removed the previously deprecated :meth:`ExtensionArray._formatting_values`. Use :attr:`ExtensionArray._formatter` instead. (:issue:`23601`) diff --git a/pandas/core/internals/blocks.py b/pandas/core/internals/blocks.py index e4de1c94da450..b0382755f2edb 100644 --- a/pandas/core/internals/blocks.py +++ b/pandas/core/internals/blocks.py @@ -2887,37 +2887,6 @@ def concat_same_type(self, to_concat, placement=None): values, placement=placement or slice(0, len(values), 1), ndim=self.ndim ) - def where( - self, - other, - cond, - align=True, - errors="raise", - try_cast: bool = False, - axis: int = 0, - ) -> List["Block"]: - # TODO(CategoricalBlock.where): - # This can all be deleted in favor of ExtensionBlock.where once - # we enforce the deprecation. - object_msg = ( - "Implicitly converting categorical to object-dtype ndarray. " - "One or more of the values in 'other' are not present in this " - "categorical's categories. A future version of pandas will raise " - "a ValueError when 'other' contains different categories.\n\n" - "To preserve the current behavior, add the new categories to " - "the categorical before calling 'where', or convert the " - "categorical to a different dtype." - ) - try: - # Attempt to do preserve categorical dtype. - result = super().where(other, cond, align, errors, try_cast, axis) - except (TypeError, ValueError): - warnings.warn(object_msg, FutureWarning, stacklevel=6) - result = self.astype(object).where( - other, cond, align=align, errors=errors, try_cast=try_cast, axis=axis - ) - return result - def replace( self, to_replace, diff --git a/pandas/tests/arrays/categorical/test_indexing.py b/pandas/tests/arrays/categorical/test_indexing.py index 6edd7fd00b707..f929eb24c9f19 100644 --- a/pandas/tests/arrays/categorical/test_indexing.py +++ b/pandas/tests/arrays/categorical/test_indexing.py @@ -206,13 +206,11 @@ def test_where_other_categorical(self): expected = pd.Series(Categorical(["a", "c", "c"], dtype=ser.dtype)) tm.assert_series_equal(result, expected) - def test_where_warns(self): + def test_where_new_category_raises(self): ser = pd.Series(Categorical(["a", "b", "c"])) - with tm.assert_produces_warning(FutureWarning): - result = ser.where([True, False, True], "d") - - expected = pd.Series(np.array(["a", "d", "c"], dtype="object")) - tm.assert_series_equal(result, expected) + msg = "Cannot setitem on a Categorical with a new category" + with pytest.raises(ValueError, match=msg): + ser.where([True, False, True], "d") def test_where_ordered_differs_rasies(self): ser = pd.Series( @@ -221,11 +219,8 @@ def test_where_ordered_differs_rasies(self): other = Categorical( ["b", "c", "a"], categories=["a", "c", "b", "d"], ordered=True ) - with tm.assert_produces_warning(FutureWarning): - result = ser.where([True, False, True], other) - - expected = pd.Series(np.array(["a", "c", "c"], dtype=object)) - tm.assert_series_equal(result, expected) + with pytest.raises(ValueError, match="without identical categories"): + ser.where([True, False, True], other) @pytest.mark.parametrize("index", [True, False])