Skip to content

Commit c962c0b

Browse files
committed
Merge pull request #10464 from sinhrks/categorical_map
BUG: Series.map using categorical Series raises AttributeError
2 parents c4c5d44 + 762d680 commit c962c0b

File tree

5 files changed

+63
-3
lines changed

5 files changed

+63
-3
lines changed

doc/source/whatsnew/v0.17.0.txt

+2-2
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,8 @@ Bug Fixes
124124

125125

126126
- Bug in ``test_categorical`` on big-endian builds (:issue:`10425`)
127-
128-
127+
- Bug in ``Series.map`` using categorical ``Series`` raises ``AttributeError`` (:issue:`10324`)
128+
- Bug in ``MultiIndex.get_level_values`` including ``Categorical`` raises ``AttributeError`` (:issue:`10460`)
129129

130130
- Bug that caused segfault when resampling an empty Series (:issue:`10228`)
131131
- Bug in ``DatetimeIndex`` and ``PeriodIndex.value_counts`` resets name from its result, but retains in result's ``Index``. (:issue:`10150`)

pandas/core/common.py

+5
Original file line numberDiff line numberDiff line change
@@ -782,6 +782,11 @@ def take_nd(arr, indexer, axis=0, out=None, fill_value=np.nan,
782782
will be done. This short-circuits computation of a mask. Result is
783783
undefined if allow_fill == False and -1 is present in indexer.
784784
"""
785+
786+
if is_categorical(arr):
787+
return arr.take_nd(indexer, fill_value=fill_value,
788+
allow_fill=allow_fill)
789+
785790
if indexer is None:
786791
indexer = np.arange(arr.shape[axis], dtype=np.int64)
787792
dtype, fill_value = arr.dtype, arr.dtype.type()

pandas/tests/test_groupby.py

+17-1
Original file line numberDiff line numberDiff line change
@@ -3476,6 +3476,13 @@ def test_groupby_categorical(self):
34763476
expected.index.names = ['myfactor', None]
34773477
assert_frame_equal(desc_result, expected)
34783478

3479+
# GH 10460
3480+
expc = Categorical.from_codes(np.arange(4).repeat(8), levels, name='myfactor', ordered=True)
3481+
exp = CategoricalIndex(expc, name='myfactor')
3482+
self.assert_index_equal(desc_result.index.get_level_values(0), exp)
3483+
exp = Index(['count', 'mean', 'std', 'min', '25%', '50%', '75%', 'max'] * 4)
3484+
self.assert_index_equal(desc_result.index.get_level_values(1), exp)
3485+
34793486
def test_groupby_datetime_categorical(self):
34803487
# GH9049: ensure backward compatibility
34813488
levels = pd.date_range('2014-01-01', periods=4)
@@ -3488,7 +3495,8 @@ def test_groupby_datetime_categorical(self):
34883495

34893496
expected = data.groupby(np.asarray(cats)).mean()
34903497
expected = expected.reindex(levels)
3491-
expected.index = CategoricalIndex(expected.index,categories=expected.index,name='myfactor',ordered=True)
3498+
expected.index = CategoricalIndex(expected.index, categories=expected.index,
3499+
name='myfactor', ordered=True)
34923500

34933501
assert_frame_equal(result, expected)
34943502
self.assertEqual(result.index.name, cats.name)
@@ -3503,6 +3511,14 @@ def test_groupby_datetime_categorical(self):
35033511
expected.index.names = ['myfactor', None]
35043512
assert_frame_equal(desc_result, expected)
35053513

3514+
# GH 10460
3515+
expc = Categorical.from_codes(np.arange(4).repeat(8), levels, name='myfactor', ordered=True)
3516+
exp = CategoricalIndex(expc, name='myfactor')
3517+
self.assert_index_equal(desc_result.index.get_level_values(0), exp)
3518+
exp = Index(['count', 'mean', 'std', 'min', '25%', '50%', '75%', 'max'] * 4)
3519+
self.assert_index_equal(desc_result.index.get_level_values(1), exp)
3520+
3521+
35063522
def test_groupby_categorical_index(self):
35073523

35083524
levels = ['foo', 'bar', 'baz', 'qux']

pandas/tests/test_index.py

+10
Original file line numberDiff line numberDiff line change
@@ -3534,6 +3534,16 @@ def test_get_level_values(self):
35343534
expected = self.index.get_level_values(0)
35353535
self.assert_numpy_array_equal(result, expected)
35363536

3537+
# GH 10460
3538+
index = MultiIndex(levels=[CategoricalIndex(['A', 'B']),
3539+
CategoricalIndex([1, 2, 3])],
3540+
labels=[np.array([0, 0, 0, 1, 1, 1]),
3541+
np.array([0, 1, 2, 0, 1, 2])])
3542+
exp = CategoricalIndex(['A', 'A', 'A', 'B', 'B', 'B'])
3543+
self.assert_index_equal(index.get_level_values(0), exp)
3544+
exp = CategoricalIndex([1, 2 ,3, 1, 2, 3])
3545+
self.assert_index_equal(index.get_level_values(1), exp)
3546+
35373547
def test_get_level_values_na(self):
35383548
arrays = [['a', 'b', 'b'], [1, np.nan, 2]]
35393549
index = pd.MultiIndex.from_arrays(arrays)

pandas/tests/test_series.py

+29
Original file line numberDiff line numberDiff line change
@@ -5753,6 +5753,35 @@ def test_map(self):
57535753
result = self.ts.map(lambda x: x * 2)
57545754
self.assert_numpy_array_equal(result, self.ts * 2)
57555755

5756+
# GH 10324
5757+
a = Series([1, 2, 3, 4])
5758+
b = Series(["even", "odd", "even", "odd"], dtype="category")
5759+
c = Series(["even", "odd", "even", "odd"])
5760+
5761+
exp = Series(["odd", "even", "odd", np.nan], dtype="category")
5762+
self.assert_series_equal(a.map(b), exp)
5763+
exp = Series(["odd", "even", "odd", np.nan])
5764+
self.assert_series_equal(a.map(c), exp)
5765+
5766+
a = Series(['a', 'b', 'c', 'd'])
5767+
b = Series([1, 2, 3, 4], index=pd.CategoricalIndex(['b', 'c', 'd', 'e']))
5768+
c = Series([1, 2, 3, 4], index=Index(['b', 'c', 'd', 'e']))
5769+
5770+
exp = Series([np.nan, 1, 2, 3])
5771+
self.assert_series_equal(a.map(b), exp)
5772+
exp = Series([np.nan, 1, 2, 3])
5773+
self.assert_series_equal(a.map(c), exp)
5774+
5775+
a = Series(['a', 'b', 'c', 'd'])
5776+
b = Series(['B', 'C', 'D', 'E'], dtype='category',
5777+
index=pd.CategoricalIndex(['b', 'c', 'd', 'e']))
5778+
c = Series(['B', 'C', 'D', 'E'], index=Index(['b', 'c', 'd', 'e']))
5779+
5780+
exp = Series([np.nan, 'B', 'C', 'D'], dtype='category')
5781+
self.assert_series_equal(a.map(b), exp)
5782+
exp = Series([np.nan, 'B', 'C', 'D'])
5783+
self.assert_series_equal(a.map(c), exp)
5784+
57565785
def test_map_compat(self):
57575786
# related GH 8024
57585787
s = Series([True,True,False],index=[1,2,3])

0 commit comments

Comments
 (0)