-
-
Notifications
You must be signed in to change notification settings - Fork 18.4k
Allow for dict-like argument to Categorical.rename_categories #17586
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm. some small comments. pls rebase / ping on green.
doc/source/whatsnew/v0.21.0.txt
Outdated
@@ -114,7 +114,7 @@ Other Enhancements | |||
- :func:`pd.read_sas()` now recognizes much more of the most frequently used date (datetime) formats in SAS7BDAT files (:issue:`15871`). | |||
- :func:`DataFrame.items` and :func:`Series.items` is now present in both Python 2 and 3 and is lazy in all cases (:issue:`13918`, :issue:`17213`) | |||
- :func:`Styler.where` has been implemented. It is as a convenience for :func:`Styler.applymap` and enables simple DataFrame styling on the Jupyter notebook (:issue:`17474`). | |||
|
|||
- :func:`Categorical.rename_categories` now accepts a dict-like argument as `new_categories`, and only updates the categories found in that dict. (:issue:`17336`) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you update / add to the example in categorical.rst as well
pandas/core/categorical.py
Outdated
@@ -824,7 +824,11 @@ def rename_categories(self, new_categories, inplace=False): | |||
""" | |||
inplace = validate_bool_kwarg(inplace, 'inplace') | |||
cat = self if inplace else self.copy() | |||
cat.categories = new_categories | |||
if isinstance(new_categories, dict): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use is_dict_like, no need to do this as an if
if is_dict_like(new_categories):
new_categories = [new_categories.get(item, item).....]
cat.categories = new_categories
pandas/tests/test_categorical.py
Outdated
inplace=True) | ||
assert res is None | ||
tm.assert_index_equal(cat.categories, expected) | ||
# Test for dicts of smaller length |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
blank lines between sub-tests
Don't worry about the travis failures. They're unrelated and have been fixed. +1 once you change the |
0eb33fb
to
440105d
Compare
Codecov Report
@@ Coverage Diff @@
## master #17586 +/- ##
=========================================
Coverage ? 91.2%
=========================================
Files ? 163
Lines ? 49627
Branches ? 0
=========================================
Hits ? 45263
Misses ? 4364
Partials ? 0
Continue to review full report at Codecov.
|
Codecov Report
@@ Coverage Diff @@
## master #17586 +/- ##
==========================================
- Coverage 91.19% 91.18% -0.02%
==========================================
Files 163 163
Lines 49625 49627 +2
==========================================
- Hits 45257 45250 -7
- Misses 4368 4377 +9
Continue to review full report at Codecov.
|
440105d
to
16c4a9f
Compare
16c4a9f
to
d828a44
Compare
doc/source/whatsnew/v0.21.0.txt
Outdated
@@ -115,6 +115,7 @@ Other Enhancements | |||
- :func:`DataFrame.items` and :func:`Series.items` is now present in both Python 2 and 3 and is lazy in all cases (:issue:`13918`, :issue:`17213`) | |||
- :func:`Styler.where` has been implemented. It is as a convenience for :func:`Styler.applymap` and enables simple DataFrame styling on the Jupyter notebook (:issue:`17474`). | |||
- :func:`MultiIndex.is_monotonic_decreasing` has been implemented. Previously returned ``False`` in all cases. (:issue:`16554`) | |||
- :func:`Categorical.rename_categories` now accepts a dict-like argument as `new_categories`, and only updates the categories found in that dict. (:issue:`17336`) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: remove the comma before "and only updates"
pandas/core/categorical.py
Outdated
@@ -824,7 +825,11 @@ def rename_categories(self, new_categories, inplace=False): | |||
""" | |||
inplace = validate_bool_kwarg(inplace, 'inplace') | |||
cat = self if inplace else self.copy() | |||
cat.categories = new_categories | |||
if is_dict_like(new_categories): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: newline above this one.
pandas/tests/test_categorical.py
Outdated
res = cat.rename_categories({'a': 4, 'b': 3, 'c': 2, 'd': 1}) | ||
expected = Index([4, 3, 2, 1]) | ||
tm.assert_index_equal(res.categories, expected) | ||
# Test for inplace |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: newline above this one.
pandas/tests/test_categorical.py
Outdated
assert res is None | ||
|
||
tm.assert_index_equal(cat.categories, expected) | ||
# Test for dicts of smaller length |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: newline above this one.
pandas/tests/test_categorical.py
Outdated
inplace=True) | ||
assert res is None | ||
|
||
tm.assert_index_equal(cat.categories, expected) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: remove newline above this one.
pandas/tests/test_categorical.py
Outdated
res = cat.rename_categories({'a': 1, 'c': 3}) | ||
expected = Index([1, 'b', 3, 'd']) | ||
tm.assert_index_equal(res.categories, expected) | ||
# Test for dicts with bigger length |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: newline above this one.
pandas/tests/test_categorical.py
Outdated
'd': 4, 'e': 5, 'f': 6}) | ||
expected = Index([1, 2, 3, 4]) | ||
tm.assert_index_equal(res.categories, expected) | ||
# Test for dicts with no items from old categories |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: newline above this one.
pandas/tests/test_categorical.py
Outdated
# Test for dicts of smaller length | ||
cat = pd.Categorical(['a', 'b', 'c', 'd']) | ||
res = cat.rename_categories({'a': 1, 'c': 3}) | ||
expected = Index([1, 'b', 3, 'd']) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: newline above this one.
pandas/tests/test_categorical.py
Outdated
# Test for dicts with no items from old categories | ||
cat = pd.Categorical(['a', 'b', 'c', 'd']) | ||
res = cat.rename_categories({'f': 1, 'g': 3}) | ||
expected = Index(['a', 'b', 'c', 'd']) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: newline above this one.
@alanbato : LGTM as well. Bunch of nit-picking to enhance readability is all I've got above. |
Done @gfyoung. Do we wait for green again? |
@alanbato : Yes, ping us when it's green. |
@TomAugspurger @gfyoung @jreback Ping! 🌵✔️ |
Nice! I'll let @jreback look this over and merge just to double check. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm. merge away
cat.categories = new_categories | ||
|
||
if is_dict_like(new_categories): | ||
cat.categories = [new_categories.get(item, item) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
actually make sure the doc string is updated here as well (maybe add a versionchanged tag)
pandas/core/categorical.py
Outdated
|
||
Parameters | ||
---------- | ||
new_categories : Index-like | ||
new_categories : Index-like or Dict-like | ||
The renamed categories. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dict-like (>=0.21.0)
b212672
to
8863408
Compare
@jreback 🌵 ✔️ |
thanks @alanbato nice patch! |
git diff upstream/master -u -- "*.py" | flake8 --diff
Categorical.rename_categories
can now take a dict asnew_categories
and updates the categories to those found in the mapping.It will only change the categories found in the dict, and leave all others the same.
The dict can be smaller or larger, and may or may not contain mappings referencing the old categories.
Have a good day/night! 🐼 🐍