diff --git a/doc/source/release.rst b/doc/source/release.rst index cf4037303dcfa..c6a901252903f 100644 --- a/doc/source/release.rst +++ b/doc/source/release.rst @@ -74,6 +74,7 @@ Bug Fixes - Bug in version string gen. for dev versions with shallow clones / install from tarball (:issue:`6127`) - Inconsistent tz parsing Timestamp/to_datetime for current year (:issue:`5958`) - Indexing bugs with reordered indexes (:issue:`6252`, :issue:`6254`) +- Bug in ``.xs`` with a Series multiindex (:issue:`6258`, :issue:`5684`) pandas 0.13.1 ------------- diff --git a/pandas/core/generic.py b/pandas/core/generic.py index e5b2be99f6362..2ee96d660eb87 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -1262,21 +1262,17 @@ def xs(self, key, axis=0, level=None, copy=True, drop_level=True): if not copy and not isinstance(loc, slice): raise ValueError('Cannot retrieve view (copy=False)') - # level = 0 - loc_is_slice = isinstance(loc, slice) - if not loc_is_slice: - indexer = [slice(None)] * self.ndim - indexer[axis] = loc - indexer = tuple(indexer) - else: - indexer = loc + # convert to a label indexer if needed + if isinstance(loc, slice): lev_num = labels._get_level_number(level) if labels.levels[lev_num].inferred_type == 'integer': - indexer = self.index[loc] + loc = labels[loc] + + # create the tuple of the indexer + indexer = [slice(None)] * self.ndim + indexer[axis] = loc + indexer = tuple(indexer) - # select on the correct axis - if axis == 1 and loc_is_slice: - indexer = slice(None), indexer result = self.ix[indexer] setattr(result, result._get_axis_name(axis), new_ax) return result diff --git a/pandas/core/index.py b/pandas/core/index.py index bf485e40da92b..3b58b27c7569f 100644 --- a/pandas/core/index.py +++ b/pandas/core/index.py @@ -3236,7 +3236,7 @@ def _get_level_indexer(self, key, level=0): labels = self.labels[level] if level > 0 or self.lexsort_depth == 0: - return labels == loc + return np.array(labels == loc,dtype=bool) else: # sorted, so can return slice object -> view i = labels.searchsorted(loc, side='left') diff --git a/pandas/tests/test_indexing.py b/pandas/tests/test_indexing.py index 0f62b1576d316..14fce28849874 100644 --- a/pandas/tests/test_indexing.py +++ b/pandas/tests/test_indexing.py @@ -951,6 +951,24 @@ def test_series_getitem_multiindex(self): expected = Series([2,3],index=[1,2]) assert_series_equal(result,expected) + # GH6258 + s = Series([1,3,4,1,3,4], + index=MultiIndex.from_product([list('AB'), + list(date_range('20130903',periods=3))])) + result = s.xs('20130903',level=1) + expected = Series([1,1],index=list('AB')) + assert_series_equal(result,expected) + + # GH5684 + idx = MultiIndex.from_tuples([('a', 'one'), ('a', 'two'), + ('b', 'one'), ('b', 'two')]) + s = Series([1, 2, 3, 4], index=idx) + s.index.set_names(['L1', 'L2'], inplace=True) + result = s.xs('one', level='L2') + expected = Series([1, 3], index=['a', 'b']) + expected.index.set_names(['L1'], inplace=True) + assert_series_equal(result, expected) + def test_ix_general(self): # ix general issues