diff --git a/doc/source/v0.15.0.txt b/doc/source/v0.15.0.txt index b0267c3dc5163..fe5ad52397ee8 100644 --- a/doc/source/v0.15.0.txt +++ b/doc/source/v0.15.0.txt @@ -274,7 +274,7 @@ Bug Fixes - Bug in ``DatetimeIndex`` and ``PeriodIndex`` in-place addition and subtraction cause different result from normal one (:issue:`6527`) - Bug in adding and subtracting ``PeriodIndex`` with ``PeriodIndex`` raise ``TypeError`` (:issue:`7741`) - Bug in ``combine_first`` with ``PeriodIndex`` data raises ``TypeError`` (:issue:`3367`) - +- Bug in multi-index slicing with missing indexers (:issue:`7866`) - Bug in pickles contains ``DateOffset`` may raise ``AttributeError`` when ``normalize`` attribute is reffered internally (:issue:`7748`) diff --git a/pandas/core/index.py b/pandas/core/index.py index 81602d5240a08..cfac0a42eaa75 100644 --- a/pandas/core/index.py +++ b/pandas/core/index.py @@ -3638,9 +3638,17 @@ def _convert_indexer(r): ranges.append(k) elif com.is_list_like(k): # a collection of labels to include from this level (these are or'd) - ranges.append(reduce( - np.logical_or,[ _convert_indexer(self._get_level_indexer(x, level=i) - ) for x in k ])) + indexers = [] + for x in k: + try: + indexers.append(_convert_indexer(self._get_level_indexer(x, level=i))) + except (KeyError): + + # ignore not founds + continue + + ranges.append(reduce(np.logical_or,indexers)) + elif _is_null_slice(k): # empty slice pass diff --git a/pandas/tests/test_indexing.py b/pandas/tests/test_indexing.py index 64e9d18d0aa2f..6a5a433ce3e35 100644 --- a/pandas/tests/test_indexing.py +++ b/pandas/tests/test_indexing.py @@ -1941,6 +1941,39 @@ def f(): df.val['X'] self.assertRaises(KeyError, f) + + # GH 7866 + # multi-index slicing with missing indexers + s = pd.Series(np.arange(9), + index=pd.MultiIndex.from_product([['A','B','C'],['foo','bar','baz']], + names=['one','two']) + ).sortlevel() + + expected = pd.Series(np.arange(3), + index=pd.MultiIndex.from_product([['A'],['foo','bar','baz']], + names=['one','two']) + ).sortlevel() + + result = s.loc[['A']] + assert_series_equal(result,expected) + result = s.loc[['A','D']] + assert_series_equal(result,expected) + + # empty series + result = s.loc[['D']] + expected = s.loc[[]] + assert_series_equal(result,expected) + + idx = pd.IndexSlice + expected = pd.Series([0,3,6], + index=pd.MultiIndex.from_product([['A','B','C'],['foo']], + names=['one','two']) + ).sortlevel() + result = s.loc[idx[:,['foo']]] + assert_series_equal(result,expected) + result = s.loc[idx[:,['foo','bah']]] + assert_series_equal(result,expected) + def test_setitem_dtype_upcast(self): # GH3216