Skip to content

Commit 245eddf

Browse files
authored
BUG: Series.__getitem__ with CategoricalIndex[ints] listlike inconsistent with scalar (#45023)
1 parent de4d74d commit 245eddf

File tree

3 files changed

+30
-1
lines changed

3 files changed

+30
-1
lines changed

doc/source/whatsnew/v1.4.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -717,6 +717,7 @@ Indexing
717717
- Bug in :meth:`IntervalIndex.get_indexer_non_unique` returning boolean mask instead of array of integers for a non unique and non monotonic index (:issue:`44084`)
718718
- Bug in :meth:`IntervalIndex.get_indexer_non_unique` not handling targets of ``dtype`` 'object' with NaNs correctly (:issue:`44482`)
719719
- Fixed regression where a single column ``np.matrix`` was no longer coerced to a 1d ``np.ndarray`` when added to a :class:`DataFrame` (:issue:`42376`)
720+
- Bug in :meth:`Series.__getitem__` with a :class:`CategoricalIndex` of integers treating lists of integers as positional indexers, inconsistent with the behavior with a single scalar integer (:issue:`15470`,:issue:`14865`)
720721
-
721722

722723
Missing

pandas/core/indexes/category.py

+8-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,10 @@
1616
DtypeObj,
1717
npt,
1818
)
19-
from pandas.util._decorators import doc
19+
from pandas.util._decorators import (
20+
cache_readonly,
21+
doc,
22+
)
2023
from pandas.util._exceptions import find_stack_level
2124

2225
from pandas.core.dtypes.common import (
@@ -180,6 +183,10 @@ class CategoricalIndex(NDArrayBackedExtensionIndex):
180183
def _can_hold_strings(self):
181184
return self.categories._can_hold_strings
182185

186+
@cache_readonly
187+
def _should_fallback_to_positional(self) -> bool:
188+
return self.categories._should_fallback_to_positional
189+
183190
codes: np.ndarray
184191
categories: Index
185192
ordered: bool | None

pandas/tests/series/indexing/test_getitem.py

+21
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,27 @@ def test_getitem_scalar_categorical_index(self):
163163
result = ser[cats[0]]
164164
assert result == expected
165165

166+
def test_getitem_numeric_categorical_listlike_matches_scalar(self):
167+
# GH#15470
168+
ser = Series(["a", "b", "c"], index=pd.CategoricalIndex([2, 1, 0]))
169+
170+
# 0 is treated as a label
171+
assert ser[0] == "c"
172+
173+
# the listlike analogue should also be treated as labels
174+
res = ser[[0]]
175+
expected = ser.iloc[-1:]
176+
tm.assert_series_equal(res, expected)
177+
178+
res2 = ser[[0, 1, 2]]
179+
tm.assert_series_equal(res2, ser.iloc[::-1])
180+
181+
def test_getitem_integer_categorical_not_positional(self):
182+
# GH#14865
183+
ser = Series(["a", "b", "c"], index=Index([1, 2, 3], dtype="category"))
184+
assert ser.get(3) == "c"
185+
assert ser[3] == "c"
186+
166187
def test_getitem_str_with_timedeltaindex(self):
167188
rng = timedelta_range("1 day 10:11:12", freq="h", periods=500)
168189
ser = Series(np.arange(len(rng)), index=rng)

0 commit comments

Comments
 (0)