Skip to content

Commit 80621dc

Browse files
committed
DEPR: setting MultiIndex.name
1 parent e0398c4 commit 80621dc

File tree

7 files changed

+31
-11
lines changed

7 files changed

+31
-11
lines changed

doc/source/whatsnew/v3.0.0.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -806,6 +806,7 @@ Other Deprecations
806806
- Deprecated backward-compatibility behavior for :meth:`DataFrame.select_dtypes` matching "str" dtype when ``np.object_`` is specified (:issue:`61916`)
807807
- Deprecated option "future.no_silent_downcasting", as it is no longer used. In a future version accessing this option will raise (:issue:`59502`)
808808
- Deprecated passing non-Index types to :meth:`Index.join`; explicitly convert to Index first (:issue:`62897`)
809+
- Deprecated setting the :attr:`MultiIndex.name` attribute, as it is not used. Set :attr:`MultiIndex.names` instead (:issue:`11979`)
809810
- Deprecated silent casting of non-datetime 'other' to datetime in :meth:`Series.combine_first` (:issue:`62931`)
810811
- Deprecated silently casting strings to :class:`Timedelta` in binary operations with :class:`Timedelta` (:issue:`59653`)
811812
- Deprecated slicing on a :class:`Series` or :class:`DataFrame` with a :class:`DatetimeIndex` using a ``datetime.date`` object, explicitly cast to :class:`Timestamp` instead (:issue:`35830`)

pandas/core/groupby/generic.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2180,7 +2180,7 @@ def _wrap_applied_output_series(
21802180

21812181
index = key_index
21822182
columns = first_not_none.index.copy()
2183-
if columns.name is None:
2183+
if columns.name is None and not isinstance(columns, MultiIndex):
21842184
# GH6124 - propagate name of Series when it's consistent
21852185
names = {v.name for v in values}
21862186
if len(names) == 1:

pandas/core/indexes/base.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1802,6 +1802,15 @@ def name(self, value: Hashable) -> None:
18021802
"Cannot set name on a level of a MultiIndex. Use "
18031803
"'MultiIndex.set_names' instead."
18041804
)
1805+
if self._is_multi:
1806+
warnings.warn(
1807+
# GH#11979
1808+
"Setting .name on a MultiIndex is deprecated and will "
1809+
"raise in a future version. Set 'names' instead.",
1810+
Pandas4Warning,
1811+
stacklevel=find_stack_level(),
1812+
)
1813+
18051814
maybe_extract_name(value, None, type(self))
18061815
self._name = value
18071816

@@ -6188,7 +6197,10 @@ def _get_indexer_strict(self, key, axis_name: str_t) -> tuple[Index, np.ndarray]
61886197
keyarr = self.take(indexer)
61896198
if isinstance(key, Index):
61906199
# GH 42790 - Preserve name from an Index
6191-
keyarr.name = key.name
6200+
if keyarr._is_multi:
6201+
keyarr.names = key.names
6202+
else:
6203+
keyarr.name = key.name
61926204
if lib.is_np_dtype(keyarr.dtype, "mM") or isinstance(
61936205
keyarr.dtype, DatetimeTZDtype
61946206
):

pandas/tests/indexes/test_any_index.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -110,10 +110,12 @@ def test_pickle_roundtrip(self, index):
110110
assert index.equal_levels(result)
111111

112112
def test_pickle_preserves_name(self, index):
113-
original_name, index.name = index.name, "foo"
113+
if not index._is_multi:
114+
original_name, index.name = index.name, "foo"
114115
unpickled = tm.round_trip_pickle(index)
115116
assert index.equals(unpickled)
116-
index.name = original_name
117+
if not index._is_multi:
118+
index.name = original_name
117119

118120

119121
class TestIndexing:
@@ -165,8 +167,10 @@ def test_getitem_error(self, index, item):
165167
class TestRendering:
166168
def test_str(self, index):
167169
# test the string repr
168-
index.name = "foo"
169-
assert "'foo'" in str(index)
170+
if index._is_multi:
171+
pytest.skip(reason=".name does not show up in repr")
172+
index.name = "my_index_name"
173+
assert "'my_index_name'" in str(index)
170174
assert type(index).__name__ in str(index)
171175

172176

pandas/tests/indexes/test_setops.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -848,10 +848,12 @@ def test_difference_name_preservation(self, index, second_name, expected, sort):
848848
def test_difference_empty_arg(self, index, sort):
849849
first = index.copy()
850850
first = first[5:20]
851-
first.name = "name"
851+
if not first._is_multi:
852+
first.name = "name"
852853
result = first.difference([], sort)
853854
expected = index[5:20].unique()
854-
expected.name = "name"
855+
if not index._is_multi:
856+
expected.name = "name"
855857
tm.assert_index_equal(result, expected)
856858

857859
def test_difference_should_not_compare(self):

pandas/tests/io/json/test_json_table_schema.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -640,7 +640,8 @@ def test_set_names_unset(self, idx, nm, prop):
640640
def test_warns_non_roundtrippable_names(self, idx):
641641
# GH 19130
642642
df = DataFrame(index=idx)
643-
df.index.name = "index"
643+
if not idx._is_multi:
644+
df.index.name = "index"
644645
with tm.assert_produces_warning(UserWarning, match="not round-trippable"):
645646
set_default_names(df)
646647

pandas/tests/resample/test_resampler_grouper.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -454,7 +454,7 @@ def test_empty(keys):
454454
.set_index(keys, drop=False)
455455
.set_index(TimedeltaIndex([]), append=True)[expected_columns]
456456
)
457-
if len(keys) == 1:
457+
if len(keys) == 1 and not expected.index._is_multi:
458458
expected.index.name = keys[0]
459459

460460
tm.assert_frame_equal(result, expected)
@@ -545,7 +545,7 @@ def test_resample_no_index(keys):
545545
expected = DataFrame(columns=["a", "b", "date"]).set_index(keys, drop=False)
546546
expected["date"] = pd.to_datetime(expected["date"])
547547
expected = expected.set_index("date", append=True, drop=True)[expected_columns]
548-
if len(keys) == 1:
548+
if len(keys) == 1 and not expected.index._is_multi:
549549
expected.index.name = keys[0]
550550

551551
tm.assert_frame_equal(result, expected)

0 commit comments

Comments
 (0)