Skip to content

Commit 5167024

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

File tree

4 files changed

+38
-3
lines changed

4 files changed

+38
-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

+26
Original file line numberDiff line numberDiff line change
@@ -754,3 +754,29 @@ 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(
759+
"idx_values", [[1, 2, 3], [-1, -2, -3], [1.5, 2.5, 3.5], [-1.5, -2.5, -3.5],]
760+
)
761+
def test_loc_with_non_string_categories(self, idx_values, ordered_fixture):
762+
# GH-17569
763+
cat_idx = CategoricalIndex(idx_values, ordered=ordered_fixture)
764+
cat = DataFrame({"A": ["foo", "bar", "baz"]}, index=cat_idx)
765+
# scalar
766+
result = cat.loc[idx_values[0]]
767+
expected = Series(["foo"], index=["A"], name=idx_values[0])
768+
tm.assert_series_equal(result, expected)
769+
# list
770+
result = cat.loc[idx_values[:2]]
771+
expected = DataFrame(["foo", "bar"], index=cat_idx[:2], columns=["A"])
772+
tm.assert_frame_equal(result, expected)
773+
# scalar assignment
774+
result = cat.copy()
775+
result.loc[idx_values[0]] = "qux"
776+
expected = DataFrame({"A": ["qux", "bar", "baz"]}, index=cat_idx)
777+
tm.assert_frame_equal(result, expected)
778+
# list assignment
779+
result = cat.copy()
780+
result.loc[idx_values[:2], "A"] = ["qux", "qux2"]
781+
expected = DataFrame({"A": ["qux", "qux2", "baz"]}, index=cat_idx)
782+
tm.assert_frame_equal(result, expected)

pandas/tests/indexing/test_floats.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,12 @@ 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 {
104+
"categorical",
105+
"string",
106+
"unicode",
107+
"mixed",
108+
}:
104109
error = KeyError
105110
msg = r"^3$"
106111
else:

0 commit comments

Comments
 (0)