diff --git a/doc/source/whatsnew/v0.23.1.txt b/doc/source/whatsnew/v0.23.1.txt index b0e08e8583cd1..fc6f3f3bfa614 100644 --- a/doc/source/whatsnew/v0.23.1.txt +++ b/doc/source/whatsnew/v0.23.1.txt @@ -80,6 +80,7 @@ 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 raised for a ``MultiIndex`` with ``nlevels == 1`` (:issue:`21149`) - I/O diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index f79288c167356..25d4e1be983e7 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -1384,7 +1384,8 @@ def set_names(self, names, level=None, inplace=False): 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..0ab3447909d9b 100644 --- a/pandas/tests/indexes/test_multi.py +++ b/pandas/tests/indexes/test_multi.py @@ -165,6 +165,22 @@ def test_set_name_methods(self): assert res is None assert ind.names == new_names2 + @pytest.mark.parametrize('inplace', [True, False]) + def test_set_names_with_nlevel_1(self, inplace): + # GH 21149 + # Ensure that .set_names for MultiIndex with + # nlevels == 1 does not raise any errors + expected = pd.MultiIndex(levels=[[0, 1]], + labels=[[0, 1]], + names=['first']) + m = pd.MultiIndex.from_product([[0, 1]]) + result = m.set_names('first', level=0, inplace=inplace) + + if inplace: + result = m + + tm.assert_index_equal(result, expected) + def test_set_levels_labels_directly(self): # setting levels/labels directly raises AttributeError