-
-
Notifications
You must be signed in to change notification settings - Fork 18.4k
ENH: Implement dict-like support for rename and set_names in MultiIndex #38126
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
Changes from 10 commits
d95308f
d1ec051
da475c7
00c0134
de76243
dbfce8d
0f4d773
a56a04b
dd49505
b346427
2df5ccf
02c7909
ad5fe75
0f5f6e1
b4767d2
c9f7264
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -73,6 +73,7 @@ | |
ABCSeries, | ||
ABCTimedeltaIndex, | ||
) | ||
from pandas.core.dtypes.inference import is_dict_like | ||
from pandas.core.dtypes.missing import array_equivalent, isna | ||
|
||
from pandas.core import missing, ops | ||
|
@@ -1319,11 +1320,18 @@ def set_names(self, names, level=None, inplace: bool = False): | |
|
||
Parameters | ||
---------- | ||
names : label or list of label | ||
|
||
names : label or list of label or dict-like for MultiIndex | ||
Name(s) to set. | ||
|
||
.. versionchanged:: 1.2.0 | ||
|
||
level : int, label or list of int or label, optional | ||
If the index is a MultiIndex, level(s) to set (None for all | ||
levels). Otherwise level must be None. | ||
If the index is a MultiIndex and names is not dict-like, level(s) to set | ||
jreback marked this conversation as resolved.
Show resolved
Hide resolved
|
||
(None for all levels). Otherwise level must be None. | ||
|
||
.. versionchanged:: 1.2.0 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 1.3 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
|
||
inplace : bool, default False | ||
Modifies the object directly, instead of creating a new Index or | ||
MultiIndex. | ||
|
@@ -1366,16 +1374,37 @@ def set_names(self, names, level=None, inplace: bool = False): | |
( 'cobra', 2018), | ||
( 'cobra', 2019)], | ||
names=['species', 'year']) | ||
|
||
When renaming levels through a dictionary no level can't be passed. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When renaming levels with a dict, levels can not be passed. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
|
||
>>> idx.set_names({'kind': 'snake'}) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. add a comment on this example (skip a line) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
MultiIndex([('python', 2018), | ||
('python', 2019), | ||
( 'cobra', 2018), | ||
( 'cobra', 2019)], | ||
names=['snake', 'year']) | ||
""" | ||
if level is not None and not isinstance(self, ABCMultiIndex): | ||
raise ValueError("Level must be None for non-MultiIndex") | ||
|
||
if level is not None and not is_list_like(level) and is_list_like(names): | ||
elif level is not None and not is_list_like(level) and is_list_like(names): | ||
raise TypeError("Names must be a string when a single level is provided.") | ||
|
||
if not is_list_like(names) and level is None and self.nlevels > 1: | ||
elif not is_list_like(names) and level is None and self.nlevels > 1: | ||
raise TypeError("Must pass list-like as `names`.") | ||
|
||
elif is_dict_like(names) and not isinstance(self, ABCMultiIndex): | ||
raise TypeError("Can only pass dict-like as `names` for MultiIndex.") | ||
jreback marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
if isinstance(self, ABCMultiIndex) and is_dict_like(names) and level is None: | ||
# Transform dict to list of new names and corresponding levels | ||
level, names_adjusted = [], [] | ||
for i, name in enumerate(self.names): | ||
if name in names.keys(): | ||
level.append(i) | ||
names_adjusted.append(names[name]) | ||
names = names_adjusted | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. doesn't this hit a dict-like names? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yikes, yes you are right. have not though about dict like names. Removed this |
||
if not is_list_like(names): | ||
names = [names] | ||
if level is not None and not is_list_like(level): | ||
|
@@ -1385,6 +1414,7 @@ def set_names(self, names, level=None, inplace: bool = False): | |
idx = self | ||
else: | ||
idx = self._shallow_copy() | ||
|
||
idx._set_names(names, level=level) | ||
if not inplace: | ||
return idx | ||
|
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.
change to 1.3
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.
Thx
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.
Done