Skip to content
Merged
1 change: 1 addition & 0 deletions doc/source/whatsnew/v1.3.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -674,6 +674,7 @@ Deprecations
- Deprecated setting :attr:`Categorical._codes`, create a new :class:`Categorical` with the desired codes instead (:issue:`40606`)
- Deprecated behavior of :meth:`DatetimeIndex.union` with mixed timezones; in a future version both will be cast to UTC instead of object dtype (:issue:`39328`)
- Deprecated using ``usecols`` with out of bounds indices for ``read_csv`` with ``engine="c"`` (:issue:`25623`)
- Deprecated passing arguments as positional in :meth:`Index.set_names` and :meth:`MultiIndex.set_names` (except for ``names``) (:issue:`41485`)
- Deprecated special treatment of lists with first element a Categorical in the :class:`DataFrame` constructor; pass as ``pd.DataFrame({col: categorical, ...})`` instead (:issue:`38845`)
- Deprecated passing arguments as positional (except for ``"method"``) in :meth:`DataFrame.interpolate` and :meth:`Series.interpolate` (:issue:`41485`)
- Deprecated passing arguments (apart from ``value``) as positional in :meth:`DataFrame.fillna` and :meth:`Series.fillna` (:issue:`41485`)
Expand Down
3 changes: 2 additions & 1 deletion pandas/core/indexes/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
from pandas.util._decorators import (
Appender,
cache_readonly,
deprecate_nonkeyword_arguments,
doc,
)

Expand Down Expand Up @@ -1529,7 +1530,7 @@ def _set_names(self, values, level=None) -> None:

names = property(fset=_set_names, fget=_get_names)

@final
@deprecate_nonkeyword_arguments(version=None, allowed_args=["self", "names"])
def set_names(self, names, level=None, inplace: bool = False):
"""
Set Index or MultiIndex name.
Expand Down
9 changes: 7 additions & 2 deletions pandas/core/indexes/multi.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
from pandas.util._decorators import (
Appender,
cache_readonly,
deprecate_nonkeyword_arguments,
doc,
)

Expand Down Expand Up @@ -295,7 +296,6 @@ class MultiIndex(Index):
_levels = FrozenList()
_codes = FrozenList()
_comparables = ["names"]
rename = Index.set_names

sortorder: int | None

Expand Down Expand Up @@ -3788,11 +3788,16 @@ def isin(self, values, level=None) -> np.ndarray:
else:
num = self._get_level_number(level)
levs = self.get_level_values(num)

if levs.size == 0:
return np.zeros(len(levs), dtype=np.bool_)
return levs.isin(values)

@deprecate_nonkeyword_arguments(version=None, allowed_args=["self", "names"])
def set_names(self, names, level=None, inplace: bool = False) -> MultiIndex | None:
return super().set_names(names=names, level=level, inplace=inplace)

rename = set_names

# ---------------------------------------------------------------
# Arithmetic/Numeric Methods - Disabled

Expand Down
17 changes: 17 additions & 0 deletions pandas/tests/indexes/multi/test_get_set.py
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,23 @@ def test_set_names_with_nlevel_1(inplace):
tm.assert_index_equal(result, expected)


def test_multi_set_names_pos_args_deprecation():
# GH#41485
idx = MultiIndex.from_product([["python", "cobra"], [2018, 2019]])
msg = (
"In a future version of pandas all arguments of MultiIndex.set_names "
"except for the argument 'names' will be keyword-only"
)
with tm.assert_produces_warning(FutureWarning, match=msg):
result = idx.set_names(["kind", "year"], None)
expected = MultiIndex(
levels=[["python", "cobra"], [2018, 2019]],
codes=[[0, 0, 1, 1], [0, 1, 0, 1]],
names=["kind", "year"],
)
tm.assert_index_equal(result, expected)


@pytest.mark.parametrize("ordered", [True, False])
def test_set_levels_categorical(ordered):
# GH13854
Expand Down
17 changes: 17 additions & 0 deletions pandas/tests/indexes/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -1738,3 +1738,20 @@ def test_construct_from_memoryview(klass, extra_kwargs):
result = klass(memoryview(np.arange(2000, 2005)), **extra_kwargs)
expected = klass(range(2000, 2005), **extra_kwargs)
tm.assert_index_equal(result, expected)


def test_index_set_names_pos_args_deprecation():
# GH#41485
idx = Index([1, 2, 3, 4])

msg = (
"In a future version of pandas all arguments of Index.set_names "
"except for the argument 'names' will be keyword-only"
)

with tm.assert_produces_warning(FutureWarning, match=msg):
result = idx.set_names("quarter", None)

expected = Index([1, 2, 3, 4], name="quarter")

tm.assert_index_equal(result, expected)