diff --git a/doc/source/whatsnew/v0.23.1.txt b/doc/source/whatsnew/v0.23.1.txt index a071d7f3f5534..99e968d908182 100644 --- a/doc/source/whatsnew/v0.23.1.txt +++ b/doc/source/whatsnew/v0.23.1.txt @@ -78,6 +78,8 @@ Indexing - Bug in :meth:`Series.reset_index` where appropriate error was not raised with an invalid level name (:issue:`20925`) - Bug in :func:`interval_range` when ``start``/``periods`` or ``end``/``periods`` are specified with float ``start`` or ``end`` (:issue:`21161`) +- Bug in :meth:`MultiIndex.set_names` where error was raised for a MultiIndex with self.nlevels == 1 (:issue: `21149`) +- Bug in comparison operations for :class:`MultiIndex` where error was raised on equality / inequality comparison involving a MultiIndex with self.nlevels == 1 (:issue: `21149`) - I/O diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index f79288c167356..2a02e901b1002 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -96,10 +96,13 @@ def cmp_method(self, other): if needs_i8_conversion(self) and needs_i8_conversion(other): return self._evaluate_compare(other, op) + from .multi import MultiIndex if is_object_dtype(self) and self.nlevels == 1: - # don't pass MultiIndex - with np.errstate(all='ignore'): - result = ops._comp_method_OBJECT_ARRAY(op, self.values, other) + if not isinstance(self, MultiIndex): + # don't pass MultiIndex + with np.errstate(all='ignore'): + result = ops._comp_method_OBJECT_ARRAY(op, + self.values, other) else: @@ -1383,8 +1386,8 @@ def set_names(self, names, level=None, inplace=False): labels=[[0, 0, 1, 1], [0, 1, 0, 1]], names=[u'baz', u'bar']) """ - - if level is not None and self.nlevels == 1: + from .multi import MultiIndex + if level is not None and not isinstance(self, MultiIndex): raise ValueError('Level must be None for non-MultiIndex') if level is not None and not is_list_like(level) and is_list_like( diff --git a/pandas/tests/indexes/test_multi.py b/pandas/tests/indexes/test_multi.py index c9f6bc9151d00..9c45c8188c3df 100644 --- a/pandas/tests/indexes/test_multi.py +++ b/pandas/tests/indexes/test_multi.py @@ -3291,3 +3291,37 @@ def test_duplicate_multiindex_labels(self): with pytest.raises(ValueError): ind.set_levels([['A', 'B', 'A', 'A', 'B'], [2, 1, 3, -2, 5]], inplace=True) + + testdata = [ + (pd.MultiIndex.from_product([[0, 1], [1, 0]]), pd.Series(range(4)), 4), + (pd.MultiIndex.from_product([[0, 1]]), pd.Series(range(2)), 2), + ] + + @pytest.mark.parametrize("midx,idx,count", testdata) + def test_multiindex_compare(self, midx, idx, count): + # GH 21149 - change in 'def cmp_method()' + expected = pd.Series([True]).repeat(count) + expected.reset_index(drop=True, inplace=True) + result = pd.Series(midx == midx) + tm.assert_series_equal(result, expected) + result = (idx == idx) + tm.assert_series_equal(result, expected) + + expected = pd.Series([False]).repeat(count) + expected.reset_index(drop=True, inplace=True) + result = pd.Series(midx > midx) + tm.assert_series_equal(result, expected) + result = pd.Series(midx == idx) + tm.assert_series_equal(result, expected) + + with tm.assert_raises_regex(TypeError, 'not supported'): + midx > idx + + def test_multiindex_set_names(self): + # GH 21149 - change in 'def set_names()' + result = pd.MultiIndex.from_product([[0, 1]]) + result.set_names('first', level=0, inplace=True) + expected = pd.MultiIndex(levels=[[0, 1]], + labels=[[0, 1]], + names=['first']) + tm.assert_index_equal(result, expected)