Repository: pandas-dev/pandas

Issue:
PEFR/BUG/API: rename_categories with a series
```
In [2]: pd.Categorical(['a', 'b']).rename_categories(pd.Series([0, 1]))
Out[2]:
[a, b]
Categories (2, object): [a, b]
```

In 0.20.3 that was

```python
[0, 1]
Categories (2, int64): [0, 1]
In [9]:
```

Do we want to treat series like an array or a dictionary here?

(this is causing the perf slowdown in rank I think).


Discussion:
xref https://github.com/pandas-dev/pandas/pull/17586 implementing the dict-like rename.

Resolving patch:
diff --git a/pandas/core/categorical.py b/pandas/core/categorical.py
--- a/pandas/core/categorical.py
+++ b/pandas/core/categorical.py
@@ -866,11 +866,6 @@ def set_categories(self, new_categories, ordered=None, rename=False,
     def rename_categories(self, new_categories, inplace=False):
         """ Renames categories.
 
-        The new categories can be either a list-like dict-like object.
-        If it is list-like, all items must be unique and the number of items
-        in the new categories must be the same as the number of items in the
-        old categories.
-
         Raises
         ------
         ValueError
@@ -879,15 +874,30 @@ def rename_categories(self, new_categories, inplace=False):
 
         Parameters
         ----------
-        new_categories : Index-like or dict-like (>=0.21.0)
-           The renamed categories.
+        new_categories : list-like or dict-like
+
+           * list-like: all items must be unique and the number of items in
+             the new categories must match the existing number of categories.
+
+           * dict-like: specifies a mapping from
+             old categories to new. Categories not contained in the mapping
+             are passed through and extra categories in the mapping are
+             ignored. *New in version 0.21.0*.
+
+           .. warning::
+
+              Currently, Series are considered list like. In a future version
+              of pandas they'll be considered dict-like.
+
         inplace : boolean (default: False)
            Whether or not to rename the categories inplace or return a copy of
            this categorical with renamed categories.
 
         Returns
         -------
-        cat : Categorical with renamed categories added or None if inplace.
+        cat : Categorical or None
+           With ``inplace=False``, the new categorical is returned.
+           With ``inplace=True``, there is no return value.
 
         See also
         --------
@@ -896,10 +906,33 @@ def rename_categories(self, new_categories, inplace=False):
         remove_categories
         remove_unused_categories
         set_categories
+
+        Examples
+        --------
+        >>> c = Categorical(['a', 'a', 'b'])
+        >>> c.rename_categories([0, 1])
+        [0, 0, 1]
+        Categories (2, int64): [0, 1]
+
+        For dict-like ``new_categories``, extra keys are ignored and
+        categories not in the dictionary are passed through
+
+        >>> c.rename_categories({'a': 'A', 'c': 'C'})
+        [A, A, b]
+        Categories (2, object): [A, b]
         """
         inplace = validate_bool_kwarg(inplace, 'inplace')
         cat = self if inplace else self.copy()
 
+        if isinstance(new_categories, ABCSeries):
+            msg = ("Treating Series 'new_categories' as a list-like and using "
+                   "the values. In a future version, 'rename_categories' will "
+                   "treat Series like a dictionary.\n"
+                   "For dict-like, use 'new_categories.to_dict()'\n"
+                   "For list-like, use 'new_categories.values'.")
+            warn(msg, FutureWarning, stacklevel=2)
+            new_categories = list(new_categories)
+
         if is_dict_like(new_categories):
             cat.categories = [new_categories.get(item, item)
                               for item in cat.categories]


Test patch:
diff --git a/pandas/tests/test_categorical.py b/pandas/tests/test_categorical.py
--- a/pandas/tests/test_categorical.py
+++ b/pandas/tests/test_categorical.py
@@ -1203,6 +1203,18 @@ def test_rename_categories(self):
         with pytest.raises(ValueError):
             cat.rename_categories([1, 2])
 
+    def test_rename_categories_series(self):
+        # https://github.com/pandas-dev/pandas/issues/17981
+        c = pd.Categorical(['a', 'b'])
+        xpr = "Treating Series 'new_categories' as a list-like "
+        with tm.assert_produces_warning(FutureWarning) as rec:
+            result = c.rename_categories(pd.Series([0, 1]))
+
+        assert len(rec) == 1
+        assert xpr in str(rec[0].message)
+        expected = pd.Categorical([0, 1])
+        tm.assert_categorical_equal(result, expected)
+
     def test_rename_categories_dict(self):
         # GH 17336
         cat = pd.Categorical(['a', 'b', 'c', 'd'])