diff --git a/doc/source/whatsnew/v0.20.0.txt b/doc/source/whatsnew/v0.20.0.txt index 49d0a6efe6781..c57d92755b129 100644 --- a/doc/source/whatsnew/v0.20.0.txt +++ b/doc/source/whatsnew/v0.20.0.txt @@ -297,7 +297,7 @@ Bug Fixes - Bug in ``pd.to_numeric()`` in which float and unsigned integer elements were being improperly casted (:issue:`14941`, :issue:`15005`) - Bug in ``pd.read_csv()`` in which the ``dialect`` parameter was not being verified before processing (:issue:`14898`) - +- Bug in ``DataFrame`` where indexing a ``MultiIndex`` using a ``Series`` failed (:issue:`14730`) - 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`) diff --git a/pandas/core/indexing.py b/pandas/core/indexing.py index dad5bf5bc70ba..9fa5b67083b2d 100755 --- a/pandas/core/indexing.py +++ b/pandas/core/indexing.py @@ -1461,6 +1461,9 @@ def _getitem_axis(self, key, axis=0): if isinstance(labels, MultiIndex): 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 diff --git a/pandas/tests/indexes/test_multi.py b/pandas/tests/indexes/test_multi.py index ccbe65e58a1a5..7da3cb377e63d 100644 --- a/pandas/tests/indexes/test_multi.py +++ b/pandas/tests/indexes/test_multi.py @@ -1,26 +1,29 @@ # -*- coding: utf-8 -*- -from datetime import timedelta -from itertools import product -import nose import re import warnings -from pandas import (DataFrame, date_range, period_range, MultiIndex, Index, - CategoricalIndex, compat) -from pandas.core.common import PerformanceWarning, UnsortedIndexError -from pandas.indexes.base import InvalidIndexError -from pandas.compat import range, lrange, u, PY3, long, lzip +from datetime import timedelta +from itertools import product + +import nose import numpy as np -from pandas.util.testing import (assert_almost_equal, assertRaises, - assertRaisesRegexp, assert_copy) +import pandas as pd + +from pandas import (CategoricalIndex, DataFrame, Index, MultiIndex, + compat, date_range, period_range) +from pandas.compat import PY3, long, lrange, lzip, range, u +from pandas.core.common import PerformanceWarning, UnsortedIndexError +from pandas.indexes.base import InvalidIndexError +from pandas.lib import Timestamp import pandas.util.testing as tm -import pandas as pd -from pandas.lib import Timestamp +from pandas.util.testing import (assertRaises, assertRaisesRegexp, + assert_almost_equal, assert_copy) + from .common import Base diff --git a/pandas/tests/test_multilevel.py b/pandas/tests/test_multilevel.py index 4e7ace4173227..8f4eaa0338c80 100755 --- a/pandas/tests/test_multilevel.py +++ b/pandas/tests/test_multilevel.py @@ -690,6 +690,25 @@ def test_getitem_partial(self): expected.columns = expected.columns.droplevel(0).droplevel(0) assert_frame_equal(result, expected) + def test_series_index(self): + # GH14730 + index = MultiIndex.from_product([[1, 2, 3], ['A', 'B', 'C']]) + x = Series(index=index, data=range(9), dtype=np.float64) + y = Series([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] + result2 = x.loc[[1, 3]] + tm.assert_series_equal(result, expected) + tm.assert_series_equal(result2, expected) + empty_series = Series(data=[], dtype=np.float64) + expected2 = Series([], index=MultiIndex( + levels=index.levels, labels=[[], []], dtype=np.float64)) + result3 = x.loc[empty_series] + tm.assert_series_equal(result3, expected2) + def test_getitem_slice_not_sorted(self): df = self.frame.sortlevel(1).T