Skip to content

Commit 49eb424

Browse files
committed
BUG: TypeError when loc-indexing on a CategoricalIndex with integer categories
1 parent ea2e26a commit 49eb424

File tree

4 files changed

+37
-3
lines changed

4 files changed

+37
-3
lines changed

doc/source/whatsnew/v1.0.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -570,6 +570,7 @@ Indexing
570570
- Fix assignment of column via `.loc` with numpy non-ns datetime type (:issue:`27395`)
571571
- Bug in :meth:`Float64Index.astype` where ``np.inf`` was not handled properly when casting to an integer dtype (:issue:`28475`)
572572
- :meth:`Index.union` could fail when the left contained duplicates (:issue:`28257`)
573+
- Bug when indexing with ``.loc`` where the index was a :class:`CategoricalIndex` with integer or float categories, a ValueError was raised (:issue:`17569`)
573574
- :meth:`Index.get_indexer_non_unique` could fail with `TypeError` in some cases, such as when searching for ints in a string index (:issue:`28257`)
574575
- Bug in :meth:`Float64Index.get_loc` incorrectly raising ``TypeError`` instead of ``KeyError`` (:issue:`29189`)
575576

pandas/core/indexes/category.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -696,8 +696,11 @@ def get_indexer_non_unique(self, target):
696696

697697
@Appender(_index_shared_docs["_convert_scalar_indexer"])
698698
def _convert_scalar_indexer(self, key, kind=None):
699-
if self.categories._defer_to_indexing:
700-
return self.categories._convert_scalar_indexer(key, kind=kind)
699+
if kind == "loc" or self.categories._defer_to_indexing:
700+
try:
701+
return self.categories._convert_scalar_indexer(key, kind=kind)
702+
except TypeError:
703+
self._invalid_indexer("label", key=key)
701704

702705
return super()._convert_scalar_indexer(key, kind=kind)
703706

pandas/tests/indexing/test_categorical.py

+29
Original file line numberDiff line numberDiff line change
@@ -754,3 +754,32 @@ def test_map_with_dict_or_series(self):
754754
output = cur_index.map(mapper)
755755
# Order of categories in output can be different
756756
tm.assert_index_equal(expected, output)
757+
758+
@pytest.mark.parametrize("idx_values", [
759+
[1, 2, 3],
760+
[-1, -2, -3],
761+
[1.5, 2.5, 3.5],
762+
[-1.5, -2.5, -3.5],
763+
])
764+
def test_loc_with_non_string_categories(self, idx_values, ordered_fixture):
765+
# GH-17569
766+
cat_idx = CategoricalIndex(idx_values, ordered=ordered_fixture)
767+
cat = DataFrame({"A": ["foo", "bar", "baz"]}, index=cat_idx)
768+
# scalar
769+
result = cat.loc[idx_values[0]]
770+
expected = Series(["foo"], index=["A"], name=idx_values[0])
771+
tm.assert_series_equal(result, expected)
772+
# list
773+
result = cat.loc[idx_values[:2]]
774+
expected = DataFrame(["foo", "bar"], index=cat_idx[:2], columns=["A"])
775+
tm.assert_frame_equal(result, expected)
776+
# scalar assignment
777+
result = cat.copy()
778+
result.loc[idx_values[0]] = "qux"
779+
expected = DataFrame({"A": ["qux", "bar", "baz"]}, index=cat_idx)
780+
tm.assert_frame_equal(result, expected)
781+
# list assignment
782+
result = cat.copy()
783+
result.loc[idx_values[:2], "A"] = ["qux", "qux2"]
784+
expected = DataFrame({"A": ["qux", "qux2", "baz"]}, index=cat_idx)
785+
tm.assert_frame_equal(result, expected)

pandas/tests/indexing/test_floats.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,8 @@ def test_scalar_non_numeric(self):
100100
idxr(s)[3.0]
101101

102102
# label based can be a TypeError or KeyError
103-
if s.index.inferred_type in ["string", "unicode", "mixed"]:
103+
if s.index.inferred_type in {"categorical", "string", "unicode",
104+
"mixed"}:
104105
error = KeyError
105106
msg = r"^3$"
106107
else:

0 commit comments

Comments
 (0)