Skip to content

Commit 03c34be

Browse files
committed
BUG: Fix MultiIndex .loc with all numpy arrays
1 parent 718d067 commit 03c34be

File tree

3 files changed

+35
-2
lines changed

3 files changed

+35
-2
lines changed

doc/source/whatsnew/v0.23.0.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -767,6 +767,7 @@ Indexing
767767
- Bug in :class:`IntervalIndex` where empty and purely NA data was constructed inconsistently depending on the construction method (:issue:`18421`)
768768
- Bug in :func:`IntervalIndex.symmetric_difference` where the symmetric difference with a non-``IntervalIndex`` did not raise (:issue:`18475`)
769769
- Bug in :class:`IntervalIndex` where set operations that returned an empty ``IntervalIndex`` had the wrong dtype (:issue:`19101`)
770+
- Bug in indexing where nested indexers having only numpy arrays are handled incorrectly (:issue:`19686`)
770771

771772
MultiIndex
772773
^^^^^^^^^^

pandas/core/indexing.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2107,10 +2107,9 @@ def is_nested_tuple(tup, labels):
21072107
if not isinstance(tup, tuple):
21082108
return False
21092109

2110-
# are we nested tuple of: tuple,list,slice
21112110
for i, k in enumerate(tup):
21122111

2113-
if isinstance(k, (tuple, list, slice)):
2112+
if is_list_like(k) or isinstance(k, slice):
21142113
return isinstance(labels, MultiIndex)
21152114

21162115
return False

pandas/tests/indexing/test_loc.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -711,3 +711,36 @@ def test_identity_slice_returns_new_object(self):
711711

712712
original_series[:3] = [7, 8, 9]
713713
assert all(sliced_series[:3] == [7, 8, 9])
714+
715+
@pytest.mark.parametrize('indexer_type_1',
716+
(list, tuple, set, slice, np.ndarray, Series))
717+
@pytest.mark.parametrize('indexer_type_2',
718+
(list, tuple, set, slice, np.ndarray, Series))
719+
def test_loc_getitem_nested_indexer(self, indexer_type_1, indexer_type_2):
720+
721+
def convert_nested_indexer(indexer_type, keys):
722+
if indexer_type == np.ndarray:
723+
return np.array(keys)
724+
if indexer_type == slice:
725+
return slice(*keys)
726+
return indexer_type(keys)
727+
728+
a = [10, 20, 30]
729+
b = [1, 2, 3]
730+
index = pd.MultiIndex.from_product([a, b])
731+
df = pd.DataFrame(np.arange(len(index)), index=index, columns=['Data'])
732+
733+
keys = ([10, 20], [2, 3])
734+
types = (indexer_type_1, indexer_type_2)
735+
# check indexers with all the combinations of nested objects
736+
# of all the valid types
737+
indexer = tuple(
738+
convert_nested_indexer(indexer_type, k)
739+
for indexer_type, k in zip(types, keys))
740+
741+
result = df.loc[indexer, 'Data']
742+
expected = pd.Series(
743+
[1, 2, 4, 5], name='Data',
744+
index=pd.MultiIndex.from_product(keys))
745+
746+
tm.assert_series_equal(result, expected)

0 commit comments

Comments
 (0)