From 1f2f38522a27ae294dcdd3dedaefac0dfab5ad89 Mon Sep 17 00:00:00 2001 From: Pietro Battiston Date: Fri, 17 Feb 2017 17:05:46 +0100 Subject: [PATCH 1/7] BUG: Fix indexing MultiIndex with Series with 0 not index --- pandas/core/indexing.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/pandas/core/indexing.py b/pandas/core/indexing.py index 66510a7708e64..878ecfaaaf338 100755 --- a/pandas/core/indexing.py +++ b/pandas/core/indexing.py @@ -1525,11 +1525,20 @@ def _getitem_axis(self, key, axis=0): # possibly convert a list-like into a nested tuple # but don't convert a list-like of tuples if isinstance(labels, MultiIndex): + if isinstance(key, ABCSeries): + # GH 14730 + key = key.values.tolist() + elif isinstance(key, ABCDataFrame): + # GH 15438 + raise NotImplementedError("Indexing a MultiIndex with a " + "DataFrame key is not " + "implemented") + elif hasattr(key, 'ndim') and key.ndim > 1: + raise NotImplementedError("Indexing a MultiIndex with a " + "multidimensional key is not " + "implemented") if (not isinstance(key, tuple) and len(key) > 1 and not isinstance(key[0], tuple)): - if isinstance(key, ABCSeries): - # GH 14730 - key = list(key) key = tuple([key]) # an iterable multi-selection From 0b719f5b41a7243777f201865b0885bb3864e917 Mon Sep 17 00:00:00 2001 From: Pietro Battiston Date: Fri, 17 Feb 2017 17:17:13 +0100 Subject: [PATCH 2/7] Test for previous commit --- pandas/tests/indexing/test_multiindex.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pandas/tests/indexing/test_multiindex.py b/pandas/tests/indexing/test_multiindex.py index b6b9ac93b234c..fe4f851332a8d 100644 --- a/pandas/tests/indexing/test_multiindex.py +++ b/pandas/tests/indexing/test_multiindex.py @@ -158,6 +158,11 @@ def test_loc_getitem_series(self): result = x.loc[[1, 3]] tm.assert_series_equal(result, expected) + # GH15424 + y1 = Series([1, 3], index=[1, 2]) + result = x.loc[y1] + tm.assert_series_equal(result, expected) + empty = Series(data=[], dtype=np.float64) expected = Series([], index=MultiIndex( levels=index.levels, labels=[[], []], dtype=np.float64)) From 7606114ca36979c91caa4c66b85d898aebfba35d Mon Sep 17 00:00:00 2001 From: Pietro Battiston Date: Fri, 17 Feb 2017 17:17:59 +0100 Subject: [PATCH 3/7] Whatsnew --- doc/source/whatsnew/v0.20.0.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v0.20.0.txt b/doc/source/whatsnew/v0.20.0.txt index 8e48dbbb083e8..a39fbae12f95b 100644 --- a/doc/source/whatsnew/v0.20.0.txt +++ b/doc/source/whatsnew/v0.20.0.txt @@ -501,7 +501,7 @@ Bug Fixes - 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`) - Bug in ``.groupby(..).resample()`` when passed the ``on=`` kwarg. (:issue:`15021`) -- Bug in ``DataFrame.loc`` with indexing a ``MultiIndex`` with a ``Series`` indexer (:issue:`14730`) +- Bug in ``DataFrame.loc`` with indexing a ``MultiIndex`` with a ``Series`` indexer (:issue:`14730`, :issue:`15424`) From 17209f3451444721ba1393b5dfb4af7f048952e7 Mon Sep 17 00:00:00 2001 From: Pietro Battiston Date: Fri, 17 Feb 2017 18:08:49 +0100 Subject: [PATCH 4/7] BUG: support indexing MultiIndex with 1-D array closes #15434 --- pandas/core/indexing.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pandas/core/indexing.py b/pandas/core/indexing.py index 878ecfaaaf338..a58a0eae8a153 100755 --- a/pandas/core/indexing.py +++ b/pandas/core/indexing.py @@ -1537,6 +1537,8 @@ def _getitem_axis(self, key, axis=0): raise NotImplementedError("Indexing a MultiIndex with a " "multidimensional key is not " "implemented") + elif isinstance(key, np.ndarray): + key = key.tolist() if (not isinstance(key, tuple) and len(key) > 1 and not isinstance(key[0], tuple)): key = tuple([key]) From 8467b5704eca590e878f4bee5dc2a3b6461e48ac Mon Sep 17 00:00:00 2001 From: Pietro Battiston Date: Fri, 17 Feb 2017 18:10:57 +0100 Subject: [PATCH 5/7] Tests for previous commit --- pandas/tests/indexing/test_multiindex.py | 29 ++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/pandas/tests/indexing/test_multiindex.py b/pandas/tests/indexing/test_multiindex.py index fe4f851332a8d..b40f0b8cd9976 100644 --- a/pandas/tests/indexing/test_multiindex.py +++ b/pandas/tests/indexing/test_multiindex.py @@ -169,6 +169,35 @@ def test_loc_getitem_series(self): result = x.loc[empty] tm.assert_series_equal(result, expected) + def test_loc_getitem_array(self): + # GH15434 + # passing an array as a key with a MultiIndex + index = MultiIndex.from_product([[1, 2, 3], ['A', 'B', 'C']]) + x = Series(index=index, data=range(9), dtype=np.float64) + y = np.array([1, 3]) + expected = Series( + data=[0, 1, 2, 6, 7, 8], + index=MultiIndex.from_product([[1, 3], ['A', 'B', 'C']]), + dtype=np.float64) + result = x.loc[y] + tm.assert_series_equal(result, expected) + + # empty array: + empty = np.array([]) + expected = Series([], index=MultiIndex( + levels=index.levels, labels=[[], []], dtype=np.float64)) + result = x.loc[empty] + tm.assert_series_equal(result, expected) + + # 0-dim array (scalar): + scalar = np.int64(1) + expected = Series( + data=[0, 1, 2], + index=['A', 'B', 'C'], + dtype=np.float64) + result = x.loc[scalar] + tm.assert_series_equal(result, expected) + def test_iloc_getitem_multiindex(self): mi_labels = DataFrame(np.random.randn(4, 3), columns=[['i', 'i', 'j'], ['A', 'A', 'B']], From 900e3ce1955f29d7edf9e440a54c8ee505aa392c Mon Sep 17 00:00:00 2001 From: Pietro Battiston Date: Fri, 17 Feb 2017 18:12:27 +0100 Subject: [PATCH 6/7] whatsnew --- doc/source/whatsnew/v0.20.0.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/source/whatsnew/v0.20.0.txt b/doc/source/whatsnew/v0.20.0.txt index a39fbae12f95b..afadcb31a8885 100644 --- a/doc/source/whatsnew/v0.20.0.txt +++ b/doc/source/whatsnew/v0.20.0.txt @@ -505,6 +505,10 @@ Bug Fixes +- Bug in ``DataFrame.loc`` with indexing a ``MultiIndex`` with a numpy array (:issue:`15434`) + + + - Bug in the display of ``.info()`` where a qualifier (+) would always be displayed with a ``MultiIndex`` that contains only non-strings (:issue:`15245`) - Bug in ``pd.read_msgpack()`` in which ``Series`` categoricals were being improperly processed (:issue:`14901`) - Bug in ``Series.ffill()`` with mixed dtypes containing tz-aware datetimes. (:issue:`14956`) From 2ba2d5d73d6c8fe15ee21e11a51bfe2d0413144c Mon Sep 17 00:00:00 2001 From: Pietro Battiston Date: Fri, 17 Feb 2017 22:48:21 +0100 Subject: [PATCH 7/7] Updated comment --- pandas/core/indexing.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/pandas/core/indexing.py b/pandas/core/indexing.py index a58a0eae8a153..b43b16ea0735c 100755 --- a/pandas/core/indexing.py +++ b/pandas/core/indexing.py @@ -1521,9 +1521,7 @@ def _getitem_axis(self, key, axis=0): return self._getbool_axis(key, axis=axis) elif is_list_like_indexer(key): - # GH 7349 - # possibly convert a list-like into a nested tuple - # but don't convert a list-like of tuples + # convert various datatypes to a list of keys if isinstance(labels, MultiIndex): if isinstance(key, ABCSeries): # GH 14730