diff --git a/doc/source/categorical.rst b/doc/source/categorical.rst index 8835c4a1533d0..65361886436d6 100644 --- a/doc/source/categorical.rst +++ b/doc/source/categorical.rst @@ -146,6 +146,8 @@ Using ``.describe()`` on categorical data will produce similar output to a `Seri df.describe() df["cat"].describe() +.. _categorical.cat: + Working with categories ----------------------- diff --git a/doc/source/whatsnew/v0.21.0.txt b/doc/source/whatsnew/v0.21.0.txt index 52e056103cbdc..d192166f620f2 100644 --- a/doc/source/whatsnew/v0.21.0.txt +++ b/doc/source/whatsnew/v0.21.0.txt @@ -566,6 +566,7 @@ Categorical - Bug in the categorical constructor with empty values and categories causing the ``.categories`` to be an empty ``Float64Index`` rather than an empty ``Index`` with object dtype (:issue:`17248`) +- Bug in categorical operations with :ref:`Series.cat ' not preserving the original Series' name (:issue:`17509`) PyPy ^^^^ diff --git a/pandas/core/categorical.py b/pandas/core/categorical.py index e67ce2936819f..ddca93f07ad5e 100644 --- a/pandas/core/categorical.py +++ b/pandas/core/categorical.py @@ -2054,9 +2054,10 @@ class CategoricalAccessor(PandasDelegate, NoNewAttributesMixin): """ - def __init__(self, values, index): + def __init__(self, values, index, name): self.categorical = values self.index = index + self.name = name self._freeze() def _delegate_property_get(self, name): @@ -2075,14 +2076,15 @@ def _delegate_method(self, name, *args, **kwargs): method = getattr(self.categorical, name) res = method(*args, **kwargs) if res is not None: - return Series(res, index=self.index) + return Series(res, index=self.index, name=self.name) @classmethod def _make_accessor(cls, data): if not is_categorical_dtype(data.dtype): raise AttributeError("Can only use .cat accessor with a " "'category' dtype") - return CategoricalAccessor(data.values, data.index) + return CategoricalAccessor(data.values, data.index, + getattr(data, 'name', None),) CategoricalAccessor._add_delegate_accessors(delegate=Categorical, diff --git a/pandas/tests/test_categorical.py b/pandas/tests/test_categorical.py index 1fa3c84dc0260..c361b430cfd8a 100644 --- a/pandas/tests/test_categorical.py +++ b/pandas/tests/test_categorical.py @@ -57,6 +57,25 @@ def test_getitem_listlike(self): expected = c[np.array([100000]).astype(np.int64)].codes tm.assert_numpy_array_equal(result, expected) + @pytest.mark.parametrize( + "method", + [ + lambda x: x.cat.set_categories([1, 2, 3]), + lambda x: x.cat.reorder_categories([2, 3, 1], ordered=True), + lambda x: x.cat.rename_categories([1, 2, 3]), + lambda x: x.cat.remove_unused_categories(), + lambda x: x.cat.remove_categories([2]), + lambda x: x.cat.add_categories([4]), + lambda x: x.cat.as_ordered(), + lambda x: x.cat.as_unordered(), + ]) + def test_getname_categorical_accessor(self, method): + # GH 17509 + s = pd.Series([1, 2, 3], name='A').astype('category') + expected = 'A' + result = method(s).name + assert result == expected + def test_getitem_category_type(self): # GH 14580 # test iloc() on Series with Categorical data