Skip to content

Commit 821be39

Browse files
toobazjreback
authored andcommitted
BUG: MultiIndex indexing with passed Series/DataFrame/ndarray as indexers
closes #15424 closes #15434 Author: Pietro Battiston <[email protected]> Closes #15425 from toobaz/mi_indexing and squashes the following commits: 2ba2d5d [Pietro Battiston] Updated comment 900e3ce [Pietro Battiston] whatsnew 8467b57 [Pietro Battiston] Tests for previous commit 17209f3 [Pietro Battiston] BUG: support indexing MultiIndex with 1-D array 7606114 [Pietro Battiston] Whatsnew 0b719f5 [Pietro Battiston] Test for previous commit 1f2f385 [Pietro Battiston] BUG: Fix indexing MultiIndex with Series with 0 not index
1 parent be4a63f commit 821be39

File tree

3 files changed

+55
-7
lines changed

3 files changed

+55
-7
lines changed

doc/source/whatsnew/v0.20.0.txt

+2-1
Original file line numberDiff line numberDiff line change
@@ -501,7 +501,8 @@ Bug Fixes
501501
- Bug in ``pd.tools.hashing.hash_pandas_object()`` in which hashing of categoricals depended on the ordering of categories, instead of just their values. (:issue:`15143`)
502502
- Bug in ``.groupby(..).resample()`` when passed the ``on=`` kwarg. (:issue:`15021`)
503503

504-
- Bug in ``DataFrame.loc`` with indexing a ``MultiIndex`` with a ``Series`` indexer (:issue:`14730`)
504+
- Bug in ``DataFrame.loc`` with indexing a ``MultiIndex`` with a ``Series`` indexer (:issue:`14730`, :issue:`15424`)
505+
- Bug in ``DataFrame.loc`` with indexing a ``MultiIndex`` with a numpy array (:issue:`15434`)
505506

506507

507508

pandas/core/indexing.py

+19-6
Original file line numberDiff line numberDiff line change
@@ -1521,15 +1521,28 @@ def _getitem_axis(self, key, axis=0):
15211521
return self._getbool_axis(key, axis=axis)
15221522
elif is_list_like_indexer(key):
15231523

1524-
# GH 7349
1525-
# possibly convert a list-like into a nested tuple
1526-
# but don't convert a list-like of tuples
1524+
# convert various list-like indexers
1525+
# to a list of keys
1526+
# we will use the *values* of the object
1527+
# and NOT the index if its a PandasObject
15271528
if isinstance(labels, MultiIndex):
1529+
1530+
if isinstance(key, (ABCSeries, np.ndarray)) and key.ndim <= 1:
1531+
# Series, or 0,1 ndim ndarray
1532+
# GH 14730
1533+
key = list(key)
1534+
elif isinstance(key, ABCDataFrame):
1535+
# GH 15438
1536+
raise NotImplementedError("Indexing a MultiIndex with a "
1537+
"DataFrame key is not "
1538+
"implemented")
1539+
elif hasattr(key, 'ndim') and key.ndim > 1:
1540+
raise NotImplementedError("Indexing a MultiIndex with a "
1541+
"multidimensional key is not "
1542+
"implemented")
1543+
15281544
if (not isinstance(key, tuple) and len(key) > 1 and
15291545
not isinstance(key[0], tuple)):
1530-
if isinstance(key, ABCSeries):
1531-
# GH 14730
1532-
key = list(key)
15331546
key = tuple([key])
15341547

15351548
# an iterable multi-selection

pandas/tests/indexing/test_multiindex.py

+34
Original file line numberDiff line numberDiff line change
@@ -158,12 +158,46 @@ def test_loc_getitem_series(self):
158158
result = x.loc[[1, 3]]
159159
tm.assert_series_equal(result, expected)
160160

161+
# GH15424
162+
y1 = Series([1, 3], index=[1, 2])
163+
result = x.loc[y1]
164+
tm.assert_series_equal(result, expected)
165+
161166
empty = Series(data=[], dtype=np.float64)
162167
expected = Series([], index=MultiIndex(
163168
levels=index.levels, labels=[[], []], dtype=np.float64))
164169
result = x.loc[empty]
165170
tm.assert_series_equal(result, expected)
166171

172+
def test_loc_getitem_array(self):
173+
# GH15434
174+
# passing an array as a key with a MultiIndex
175+
index = MultiIndex.from_product([[1, 2, 3], ['A', 'B', 'C']])
176+
x = Series(index=index, data=range(9), dtype=np.float64)
177+
y = np.array([1, 3])
178+
expected = Series(
179+
data=[0, 1, 2, 6, 7, 8],
180+
index=MultiIndex.from_product([[1, 3], ['A', 'B', 'C']]),
181+
dtype=np.float64)
182+
result = x.loc[y]
183+
tm.assert_series_equal(result, expected)
184+
185+
# empty array:
186+
empty = np.array([])
187+
expected = Series([], index=MultiIndex(
188+
levels=index.levels, labels=[[], []], dtype=np.float64))
189+
result = x.loc[empty]
190+
tm.assert_series_equal(result, expected)
191+
192+
# 0-dim array (scalar):
193+
scalar = np.int64(1)
194+
expected = Series(
195+
data=[0, 1, 2],
196+
index=['A', 'B', 'C'],
197+
dtype=np.float64)
198+
result = x.loc[scalar]
199+
tm.assert_series_equal(result, expected)
200+
167201
def test_iloc_getitem_multiindex(self):
168202
mi_labels = DataFrame(np.random.randn(4, 3),
169203
columns=[['i', 'i', 'j'], ['A', 'A', 'B']],

0 commit comments

Comments
 (0)