Skip to content

Commit 0362522

Browse files
committed
API: Restore getting name from MultiIndex level
xref https://issues.apache.org/jira/browse/ARROW-6922 / pandas-dev#27242 (comment) / pandas-dev#29032 No docs yet, since it isn't clear how this will eventually sort out. But we at least want to preserve this behavior for 1.0
1 parent 509eb14 commit 0362522

File tree

5 files changed

+27
-17
lines changed

5 files changed

+27
-17
lines changed

pandas/core/indexes/multi.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -639,7 +639,10 @@ def from_frame(cls, df, sortorder=None, names=None):
639639

640640
@property
641641
def levels(self):
642-
return self._levels
642+
result = [
643+
x._shallow_copy(name=name) for x, name in zip(self._levels, self._names)
644+
]
645+
return FrozenList(result)
643646

644647
@property
645648
def _values(self):
@@ -830,7 +833,7 @@ def _set_codes(
830833
if level is None:
831834
new_codes = FrozenList(
832835
_ensure_frozen(level_codes, lev, copy=copy)._shallow_copy()
833-
for lev, level_codes in zip(self.levels, codes)
836+
for lev, level_codes in zip(self._levels, codes)
834837
)
835838
else:
836839
level = [self._get_level_number(l) for l in level]

pandas/tests/indexes/multi/test_constructor.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ def test_constructor_single_level():
1717
levels=[["foo", "bar", "baz", "qux"]], codes=[[0, 1, 2, 3]], names=["first"]
1818
)
1919
assert isinstance(result, MultiIndex)
20-
expected = Index(["foo", "bar", "baz", "qux"])
20+
expected = Index(["foo", "bar", "baz", "qux"], name="first")
2121
tm.assert_index_equal(result.levels[0], expected)
2222
assert result.names == ["first"]
2323

@@ -292,7 +292,7 @@ def test_from_arrays_empty():
292292
# 1 level
293293
result = MultiIndex.from_arrays(arrays=[[]], names=["A"])
294294
assert isinstance(result, MultiIndex)
295-
expected = Index([])
295+
expected = Index([], name="A")
296296
tm.assert_index_equal(result.levels[0], expected)
297297
assert result.names == ["A"]
298298

@@ -440,7 +440,7 @@ def test_from_product_empty_zero_levels():
440440

441441
def test_from_product_empty_one_level():
442442
result = MultiIndex.from_product([[]], names=["A"])
443-
expected = pd.Index([])
443+
expected = pd.Index([], name="A")
444444
tm.assert_index_equal(result.levels[0], expected)
445445
assert result.names == ["A"]
446446

pandas/tests/indexes/multi/test_names.py

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ def test_index_name_retained():
2727

2828

2929
def test_changing_names(idx):
30-
assert [level.name for level in idx.levels] == [None, None]
30+
assert [level.name for level in idx.levels] == ["first", "second"]
3131

3232
view = idx.view()
3333
copy = idx.copy()
@@ -36,16 +36,16 @@ def test_changing_names(idx):
3636
# changing names should not change level names on object
3737
new_names = [name + "a" for name in idx.names]
3838
idx.names = new_names
39-
check_level_names(idx, [None, None])
39+
check_level_names(idx, ["firsta", "seconda"])
4040

4141
# and not on copies
42-
check_level_names(view, [None, None])
43-
check_level_names(copy, [None, None])
44-
check_level_names(shallow_copy, [None, None])
42+
check_level_names(view, ["first", "second"])
43+
check_level_names(copy, ["first", "second"])
44+
check_level_names(shallow_copy, ["first", "second"])
4545

4646
# and copies shouldn't change original
4747
shallow_copy.names = [name + "c" for name in shallow_copy.names]
48-
check_level_names(idx, [None, None])
48+
check_level_names(idx, ["firsta", "seconda"])
4949

5050

5151
def test_take_preserve_name(idx):
@@ -81,7 +81,7 @@ def test_names(idx, index_names):
8181
# names are assigned in setup
8282
assert index_names == ["first", "second"]
8383
level_names = [level.name for level in idx.levels]
84-
assert level_names == [None, None]
84+
assert level_names == index_names
8585

8686
# setting bad names on existing
8787
index = idx
@@ -109,11 +109,18 @@ def test_names(idx, index_names):
109109
# names are assigned on index, but not transferred to the levels
110110
index.names = ["a", "b"]
111111
level_names = [level.name for level in index.levels]
112-
assert level_names == [None, None]
112+
assert level_names == ["a", "b"]
113113

114114

115115
def test_duplicate_level_names_access_raises(idx):
116116
# GH19029
117117
idx.names = ["foo", "foo"]
118118
with pytest.raises(ValueError, match="name foo occurs multiple times"):
119119
idx._get_level_number("foo")
120+
121+
122+
def test_get_names_from_levels():
123+
idx = pd.MultiIndex.from_product([["a"], [1, 2]], names=["a", "b"])
124+
125+
assert idx.levels[0].name == "a"
126+
assert idx.levels[1].name == "b"

pandas/tests/indexes/multi/test_reindex.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@ def test_reindex(idx):
1010
result, indexer = idx.reindex(list(idx[:4]))
1111
assert isinstance(result, MultiIndex)
1212
assert result.names == ["first", "second"]
13-
assert [level.name for level in result.levels] == [None, None]
13+
assert [level.name for level in result.levels] == ["first", "second"]
1414

1515
result, indexer = idx.reindex(list(idx))
1616
assert isinstance(result, MultiIndex)
1717
assert indexer is None
1818
assert result.names == ["first", "second"]
19-
assert [level.name for level in result.levels] == [None, None]
19+
assert [level.name for level in result.levels] == ["first", "second"]
2020

2121

2222
def test_reindex_level(idx):

pandas/tests/indexes/multi/test_reshape.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@ def test_insert(idx):
1515
# key not contained in all levels
1616
new_index = idx.insert(0, ("abc", "three"))
1717

18-
exp0 = Index(list(idx.levels[0]) + ["abc"])
18+
exp0 = Index(list(idx.levels[0]) + ["abc"], name="first")
1919
tm.assert_index_equal(new_index.levels[0], exp0)
2020
assert new_index.names == ["first", "second"]
2121

22-
exp1 = Index(list(idx.levels[1]) + ["three"])
22+
exp1 = Index(list(idx.levels[1]) + ["three"], name="second")
2323
tm.assert_index_equal(new_index.levels[1], exp1)
2424
assert new_index[0] == ("abc", "three")
2525

0 commit comments

Comments
 (0)