Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DEPR: Deprecate n-dim indexing for Series #35141

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/source/whatsnew/v1.1.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -788,6 +788,7 @@ Deprecations
- :meth:`Categorical.to_dense` is deprecated and will be removed in a future version, use ``np.asarray(cat)`` instead (:issue:`32639`)
- The ``fastpath`` keyword in the ``SingleBlockManager`` constructor is deprecated and will be removed in a future version (:issue:`33092`)
- Providing ``suffixes`` as a ``set`` in :func:`pandas.merge` is deprecated. Provide a tuple instead (:issue:`33740`, :issue:`34741`).
- Indexing a series with a multi-dimensional indexer like ``[:, None]`` to return an ndarray now raises a ``FutureWarning``. Convert to a NumPy array before indexing instead (:issue:`27837`)
- :meth:`Index.is_mixed` is deprecated and will be removed in a future version, check ``index.inferred_type`` directly instead (:issue:`32922`)

- Passing any arguments but the first one to :func:`read_html` as
Expand Down
10 changes: 5 additions & 5 deletions pandas/core/indexers.py
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ def length_of_indexer(indexer, target=None) -> int:
raise AssertionError("cannot find the length of the indexer")


def deprecate_ndim_indexing(result):
def deprecate_ndim_indexing(result, stacklevel=3):
"""
Helper function to raise the deprecation warning for multi-dimensional
indexing on 1D Series/Index.
Expand All @@ -306,11 +306,11 @@ def deprecate_ndim_indexing(result):
"""
if np.ndim(result) > 1:
warnings.warn(
"Support for multi-dimensional indexing (e.g. `index[:, None]`) "
"on an Index is deprecated and will be removed in a future "
"Support for multi-dimensional indexing (e.g. `obj[:, None]`) "
"is deprecated and will be removed in a future "
"version. Convert to a numpy array before indexing instead.",
DeprecationWarning,
stacklevel=3,
FutureWarning,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Elevated to a FutureWarning. It was originally a DeprecationWarning for matplotlib.

stacklevel=stacklevel,
)


Expand Down
12 changes: 4 additions & 8 deletions pandas/core/series.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@
sanitize_array,
)
from pandas.core.generic import NDFrame
from pandas.core.indexers import unpack_1tuple
from pandas.core.indexers import deprecate_ndim_indexing, unpack_1tuple
from pandas.core.indexes.accessors import CombinedDatetimelikeProperties
from pandas.core.indexes.api import Float64Index, Index, MultiIndex, ensure_index
import pandas.core.indexes.base as ibase
Expand Down Expand Up @@ -950,13 +950,9 @@ def _get_with(self, key):
def _get_values_tuple(self, key):
# mpl hackaround
if com.any_none(*key):
# suppress warning from slicing the index with a 2d indexer.
# eventually we'll want Series itself to warn.
with warnings.catch_warnings():
warnings.filterwarnings(
"ignore", "Support for multi-dim", DeprecationWarning
)
return self._get_values(key)
result = self._get_values(key)
deprecate_ndim_indexing(result, stacklevel=5)
return result

if not isinstance(self.index, MultiIndex):
raise ValueError("Can only tuple-index with a MultiIndex")
Expand Down
2 changes: 1 addition & 1 deletion pandas/tests/indexes/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -855,7 +855,7 @@ def test_engine_reference_cycle(self):
def test_getitem_2d_deprecated(self):
# GH#30588
idx = self.create_index()
with tm.assert_produces_warning(DeprecationWarning, check_stacklevel=False):
with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
res = idx[:, None]

assert isinstance(res, np.ndarray), type(res)
Expand Down
4 changes: 2 additions & 2 deletions pandas/tests/indexes/datetimes/test_indexing.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ def test_dti_business_getitem(self):

def test_dti_business_getitem_matplotlib_hackaround(self):
rng = pd.bdate_range(START, END)
with tm.assert_produces_warning(DeprecationWarning):
with tm.assert_produces_warning(FutureWarning):
# GH#30588 multi-dimensional indexing deprecated
values = rng[:, None]
expected = rng.values[:, None]
Expand All @@ -122,7 +122,7 @@ def test_dti_custom_getitem(self):

def test_dti_custom_getitem_matplotlib_hackaround(self):
rng = pd.bdate_range(START, END, freq="C")
with tm.assert_produces_warning(DeprecationWarning):
with tm.assert_produces_warning(FutureWarning):
# GH#30588 multi-dimensional indexing deprecated
values = rng[:, None]
expected = rng.values[:, None]
Expand Down
2 changes: 1 addition & 1 deletion pandas/tests/indexes/interval/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,5 +84,5 @@ def test_getitem_2d_deprecated(self):
# GH#30588 multi-dim indexing is deprecated, but raising is also acceptable
idx = self.create_index()
with pytest.raises(ValueError, match="multi-dimensional indexing not allowed"):
with tm.assert_produces_warning(DeprecationWarning, check_stacklevel=False):
with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
idx[:, None]
4 changes: 2 additions & 2 deletions pandas/tests/indexes/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def test_can_hold_identifiers(self):

@pytest.mark.parametrize("index", ["datetime"], indirect=True)
def test_new_axis(self, index):
with tm.assert_produces_warning(DeprecationWarning):
with tm.assert_produces_warning(FutureWarning):
# GH#30588 multi-dimensional indexing deprecated
new_index = index[None, :]
assert new_index.ndim == 2
Expand Down Expand Up @@ -2531,7 +2531,7 @@ def test_shape_of_invalid_index():
# that the returned shape is consistent with this underlying array for
# compat with matplotlib (see https://github.com/pandas-dev/pandas/issues/27775)
idx = pd.Index([0, 1, 2, 3])
with tm.assert_produces_warning(DeprecationWarning):
with tm.assert_produces_warning(FutureWarning):
# GH#30588 multi-dimensional indexing deprecated
assert idx[:, None].shape == (4, 1)

Expand Down
12 changes: 7 additions & 5 deletions pandas/tests/series/indexing/test_getitem.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,7 @@ class TestSeriesGetitemSlices:
def test_getitem_slice_2d(self, datetime_series):
# GH#30588 multi-dimensional indexing deprecated

# This is currently failing because the test was relying on
# the DeprecationWarning coming through Index.__getitem__.
# We want to implement a warning specifically for Series.__getitem__
# at which point this will become a Deprecation/FutureWarning
with tm.assert_produces_warning(None):
with tm.assert_produces_warning(FutureWarning):
# GH#30867 Don't want to support this long-term, but
# for now ensure that the warning from Index
# doesn't comes through via Series.__getitem__.
Expand Down Expand Up @@ -135,3 +131,9 @@ def test_getitem_generator(string_series):
expected = string_series[string_series > 0]
tm.assert_series_equal(result, expected)
tm.assert_series_equal(result2, expected)


def test_getitem_ndim_deprecated():
s = pd.Series([0, 1])
with tm.assert_produces_warning(FutureWarning):
s[:, None]