Skip to content

Commit 96f01ac

Browse files
authored
BUG: not dropping scalar-indexes MultiIndex levels (#42319)
1 parent 4b18c90 commit 96f01ac

File tree

3 files changed

+21
-11
lines changed

3 files changed

+21
-11
lines changed

pandas/core/indexing.py

+14-6
Original file line numberDiff line numberDiff line change
@@ -825,7 +825,15 @@ def _getitem_lowerdim(self, tup: tuple):
825825
ax0 = self.obj._get_axis(0)
826826
# ...but iloc should handle the tuple as simple integer-location
827827
# instead of checking it as multiindex representation (GH 13797)
828-
if isinstance(ax0, MultiIndex) and self.name != "iloc":
828+
if (
829+
isinstance(ax0, MultiIndex)
830+
and self.name != "iloc"
831+
and not any(isinstance(x, slice) for x in tup)
832+
):
833+
# Note: in all extant test cases, replacing the slice condition with
834+
# `all(is_hashable(x) or com.is_null_slice(x) for x in tup)`
835+
# is equivalent.
836+
# (see the other place where we call _handle_lowerdim_multi_index_axis0)
829837
with suppress(IndexingError):
830838
return self._handle_lowerdim_multi_index_axis0(tup)
831839

@@ -879,7 +887,7 @@ def _getitem_nested_tuple(self, tup: tuple):
879887
):
880888
# GH#35349 Raise if tuple in tuple for series
881889
raise ValueError("Too many indices")
882-
if self.ndim == 1 or not any(isinstance(x, slice) for x in tup):
890+
if all(is_hashable(x) or com.is_null_slice(x) for x in tup):
883891
# GH#10521 Series should reduce MultiIndex dimensions instead of
884892
# DataFrame, IndexingError is not raised when slice(None,None,None)
885893
# with one row.
@@ -1117,16 +1125,16 @@ def _handle_lowerdim_multi_index_axis0(self, tup: tuple):
11171125
try:
11181126
# fast path for series or for tup devoid of slices
11191127
return self._get_label(tup, axis=axis)
1120-
except (TypeError, InvalidIndexError):
1128+
except TypeError as err:
11211129
# slices are unhashable
1122-
pass
1130+
raise IndexingError("No label returned") from err
1131+
11231132
except KeyError as ek:
11241133
# raise KeyError if number of indexers match
11251134
# else IndexingError will be raised
11261135
if self.ndim < len(tup) <= self.obj.index.nlevels:
11271136
raise ek
1128-
1129-
raise IndexingError("No label returned")
1137+
raise IndexingError("No label returned") from ek
11301138

11311139
def _getitem_axis(self, key, axis: int):
11321140
key = item_from_zerodim(key)

pandas/tests/indexing/multiindex/test_getitem.py

+5-3
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,11 @@ def test_series_getitem_multiindex(access_method, level1_value, expected):
2828
# GH 6018
2929
# series regression getitem with a multi-index
3030

31-
s = Series([1, 2, 3])
32-
s.index = MultiIndex.from_tuples([(0, 0), (1, 1), (2, 1)])
33-
result = access_method(s, level1_value)
31+
mi = MultiIndex.from_tuples([(0, 0), (1, 1), (2, 1)], names=["A", "B"])
32+
ser = Series([1, 2, 3], index=mi)
33+
expected.index.name = "A"
34+
35+
result = access_method(ser, level1_value)
3436
tm.assert_series_equal(result, expected)
3537

3638

pandas/tests/indexing/multiindex/test_loc.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -787,10 +787,10 @@ def test_loc_getitem_index_differently_ordered_slice_none_duplicates(indexer):
787787

788788

789789
def test_loc_getitem_drops_levels_for_one_row_dataframe():
790-
# GH#10521
790+
# GH#10521 "x" and "z" are both scalar indexing, so those levels are dropped
791791
mi = MultiIndex.from_arrays([["x"], ["y"], ["z"]], names=["a", "b", "c"])
792792
df = DataFrame({"d": [0]}, index=mi)
793-
expected = df.copy()
793+
expected = df.droplevel([0, 2])
794794
result = df.loc["x", :, "z"]
795795
tm.assert_frame_equal(result, expected)
796796

0 commit comments

Comments
 (0)