Skip to content

Commit 48e03f3

Browse files
authored
Fix MultiIndex .loc "Too Many Indexers" with None as return value (#34450)
1 parent e79487d commit 48e03f3

File tree

3 files changed

+32
-5
lines changed

3 files changed

+32
-5
lines changed

doc/source/whatsnew/v1.1.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -887,6 +887,7 @@ Indexing
887887
- Bug in :meth:`DataFrame.truncate` and :meth:`Series.truncate` where index was assumed to be monotone increasing (:issue:`33756`)
888888
- Indexing with a list of strings representing datetimes failed on :class:`DatetimeIndex` or :class:`PeriodIndex`(:issue:`11278`)
889889
- Bug in :meth:`Series.at` when used with a :class:`MultiIndex` would raise an exception on valid inputs (:issue:`26989`)
890+
- Bug in :meth:`Series.loc` when used with a :class:`MultiIndex` would raise an IndexingError when accessing a None value (:issue:`34318`)
890891

891892
Missing
892893
^^^^^^^

pandas/core/indexing.py

+9-5
Original file line numberDiff line numberDiff line change
@@ -768,9 +768,11 @@ def _getitem_lowerdim(self, tup: Tuple):
768768
# ...but iloc should handle the tuple as simple integer-location
769769
# instead of checking it as multiindex representation (GH 13797)
770770
if isinstance(ax0, ABCMultiIndex) and self.name != "iloc":
771-
result = self._handle_lowerdim_multi_index_axis0(tup)
772-
if result is not None:
771+
try:
772+
result = self._handle_lowerdim_multi_index_axis0(tup)
773773
return result
774+
except IndexingError:
775+
pass
774776

775777
if len(tup) > self.ndim:
776778
raise IndexingError("Too many indexers. handle elsewhere")
@@ -818,9 +820,11 @@ def _getitem_nested_tuple(self, tup: Tuple):
818820
if self.name != "loc":
819821
# This should never be reached, but lets be explicit about it
820822
raise ValueError("Too many indices")
821-
result = self._handle_lowerdim_multi_index_axis0(tup)
822-
if result is not None:
823+
try:
824+
result = self._handle_lowerdim_multi_index_axis0(tup)
823825
return result
826+
except IndexingError:
827+
pass
824828

825829
# this is a series with a multi-index specified a tuple of
826830
# selectors
@@ -1067,7 +1071,7 @@ def _handle_lowerdim_multi_index_axis0(self, tup: Tuple):
10671071
if len(tup) <= self.obj.index.nlevels and len(tup) > self.ndim:
10681072
raise ek
10691073

1070-
return None
1074+
raise IndexingError("No label returned")
10711075

10721076
def _getitem_axis(self, key, axis: int):
10731077
key = item_from_zerodim(key)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
""" test get/set & misc """
2+
3+
4+
import pandas as pd
5+
from pandas import MultiIndex, Series
6+
7+
8+
def test_access_none_value_in_multiindex():
9+
# GH34318: test that you can access a None value using .loc through a Multiindex
10+
11+
s = Series([None], pd.MultiIndex.from_arrays([["Level1"], ["Level2"]]))
12+
result = s.loc[("Level1", "Level2")]
13+
assert result is None
14+
15+
midx = MultiIndex.from_product([["Level1"], ["Level2_a", "Level2_b"]])
16+
s = Series([None] * len(midx), dtype=object, index=midx)
17+
result = s.loc[("Level1", "Level2_a")]
18+
assert result is None
19+
20+
s = Series([1] * len(midx), dtype=object, index=midx)
21+
result = s.loc[("Level1", "Level2_a")]
22+
assert result == 1

0 commit comments

Comments
 (0)