-
-
Notifications
You must be signed in to change notification settings - Fork 18.4k
Support for use of Enums in MultiIndex #21348
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 20 commits
0ec3531
ca40575
3857229
9aee04a
60c8f2a
13d67ca
e6e6627
d0607f4
ec5900a
979b61e
1c84176
e914b20
5a55fee
191fe58
bac47e2
f76d522
f125bf7
761a9d1
2e7921b
21014c6
4cd2dff
702594b
1950562
6e4485f
06437cd
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 |
---|---|---|
|
@@ -27,3 +27,4 @@ dependencies: | |
- pytest | ||
- pytest-xdist | ||
- moto | ||
- enum34 |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,6 +22,7 @@ dependencies: | |
# universal | ||
- pytest | ||
- pytest-xdist | ||
- enum34 | ||
- pip: | ||
- html5lib==1.0b2 | ||
- beautifulsoup4==4.2.1 |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -42,6 +42,7 @@ dependencies: | |
- pytest | ||
- pytest-xdist | ||
- moto | ||
- enum34 | ||
- pip: | ||
- backports.lzma | ||
- cpplint | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -132,7 +132,7 @@ Strings | |
Indexing | ||
^^^^^^^^ | ||
|
||
- | ||
- Bug in :func:`pandas.core.arrays.categorical._factorize_from_iterable` inappropriately caused ``TypeError`` to be raised when an ``Enum`` was used as a factor in a ``MultiIndex`` (:issue:`21298`) | ||
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. Release notes shouldn't reference private methods. You should be able to reference Enum with :class: |
||
- | ||
- | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2523,7 +2523,7 @@ def _factorize_from_iterable(values): | |
ordered=values.ordered) | ||
codes = values.codes | ||
else: | ||
cat = Categorical(values, ordered=True) | ||
cat = Categorical(values, ordered=False) | ||
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. Interesting that this didn't cause any testing issues... 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. Yes, it's striking. It's possible that that |
||
categories = cat.categories | ||
codes = cat.codes | ||
return codes, categories | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,7 +5,7 @@ | |
|
||
from datetime import timedelta | ||
from itertools import product | ||
|
||
from enum import Enum | ||
import pytest | ||
|
||
import numpy as np | ||
|
@@ -20,6 +20,7 @@ | |
from pandas.core.indexes.base import InvalidIndexError | ||
from pandas.core.dtypes.cast import construct_1d_object_array_from_listlike | ||
from pandas._libs.tslib import Timestamp | ||
from pandas.core.algorithms import take_1d | ||
|
||
import pandas.util.testing as tm | ||
|
||
|
@@ -3307,3 +3308,28 @@ def test_duplicate_multiindex_labels(self): | |
with pytest.raises(ValueError): | ||
ind.set_levels([['A', 'B', 'A', 'A', 'B'], [2, 1, 3, -2, 5]], | ||
inplace=True) | ||
|
||
def test_use_enum_in_multiindex(self): | ||
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. can you use 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. |
||
# GH 21298 | ||
# Allow use of Enums as one of the factors in a MultiIndex. | ||
MyEnum = Enum("MyEnum", "A B") | ||
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. you would have to add
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. ok, I've hopefully done this correctly. |
||
df = pd.DataFrame(columns=pd.MultiIndex.from_product(iterables=[ | ||
MyEnum, | ||
[1, 2] | ||
])) | ||
|
||
# cf. https://github.com/pandas-dev/pandas/blob/ | ||
# 0c65c57a279e755ab7093db925d1e580f9878dae/pandas/util/testing.py#L793-L799 | ||
unique = df.columns.levels[0] | ||
labels = df.columns.labels[0] | ||
filled = take_1d(unique.values, labels, fill_value=unique._na_value) | ||
df_index_0 = unique._shallow_copy(filled, name=df.columns.names[0]) | ||
exp_index_0 = pd.Index([MyEnum.A, MyEnum.A, MyEnum.B, MyEnum.B], | ||
dtype='object') | ||
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. this is pretty complicated, why cannot you just directly construct the Index here? 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. |
||
tm.assert_index_equal(df_index_0, exp_index_0) | ||
|
||
expected = df.copy() | ||
df = df.append({(MyEnum.A, 1): "abc", (MyEnum.B, 2): "xyz"}, | ||
ignore_index=True) | ||
expected.loc[0, [(MyEnum.A, 1), (MyEnum.B, 2)]] = 'abc', 'xyz' | ||
tm.assert_frame_equal(df, 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.
can you remove from all but 1 of the 27 compat tests (the travis-27) one
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