Skip to content

Commit 9820edc

Browse files
authored
DEPR: indexing (#49412)
* DEPR: disallow Series.__getitem__ with a single-element list containing slice * DEPR: disallow slicing with positional slicer and .loc * DEPR: disallow positional indexing with float key * move whatsnew * DEPR: disallow multi-dimensional indexing * fix matplotlib tests * update install.rst
1 parent e5961e2 commit 9820edc

File tree

16 files changed

+62
-93
lines changed

16 files changed

+62
-93
lines changed

ci/deps/actions-38-minimum_versions.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ dependencies:
3232
- gcsfs=2021.07.0
3333
- jinja2=3.0.0
3434
- lxml=4.6.3
35-
- matplotlib=3.3.2
35+
- matplotlib=3.6.0
3636
- numba=0.53.1
3737
- numexpr=2.7.3
3838
- odfpy=1.4.1

doc/source/getting_started/install.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,7 @@ Can be managed as optional_extra with ``pandas[plot, output_formatting]``, depen
310310
========================= ================== ================== =============================================================
311311
Dependency Minimum Version optional_extra Notes
312312
========================= ================== ================== =============================================================
313-
matplotlib 3.3.2 plot Plotting library
313+
matplotlib 3.6.0 plot Plotting library
314314
Jinja2 3.0.0 output_formatting Conditional formatting with DataFrame.style
315315
tabulate 0.8.9 output_formatting Printing in Markdown-friendly format (see `tabulate`_)
316316
========================= ================== ================== =============================================================

doc/source/whatsnew/v2.0.0.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,8 @@ Optional libraries below the lowest tested version may still work, but are not c
124124
+=================+=================+=========+
125125
| pyarrow | 6.0.0 | X |
126126
+-----------------+-----------------+---------+
127+
| matplotlib | 3.6.0 | X |
128+
+-----------------+-----------------+---------+
127129
| fastparquet | 0.6.3 | X |
128130
+-----------------+-----------------+---------+
129131

@@ -282,6 +284,8 @@ Removal of prior version deprecations/changes
282284
- Enforced disallowing the use of ``**kwargs`` in :class:`.ExcelWriter`; use the keyword argument ``engine_kwargs`` instead (:issue:`40430`)
283285
- Enforced disallowing a tuple of column labels into :meth:`.DataFrameGroupBy.__getitem__` (:issue:`30546`)
284286
- Enforced disallowing setting values with ``.loc`` using a positional slice. Use ``.loc`` with labels or ``.iloc`` with positions instead (:issue:`31840`)
287+
- Enforced disallowing positional indexing with a ``float`` key even if that key is a round number, manually cast to integer instead (:issue:`34193`)
288+
- Enforced disallowing indexing on a :class:`Index` or positional indexing on a :class:`Series` producing multi-dimensional objects e.g. ``obj[:, None]``, convert to numpy before indexing instead (:issue:`35141`)
285289
- Enforced disallowing ``dict`` or ``set`` objects in ``suffixes`` in :func:`merge` (:issue:`34810`)
286290
- Enforced disallowing :func:`merge` to produce duplicated columns through the ``suffixes`` keyword and already existing columns (:issue:`22818`)
287291
- Enforced disallowing using :func:`merge` or :func:`join` on a different number of levels (:issue:`34862`)

pandas/compat/_optional.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
"gcsfs": "2021.07.0",
2424
"jinja2": "3.0.0",
2525
"lxml.etree": "4.6.3",
26-
"matplotlib": "3.3.2",
26+
"matplotlib": "3.6.0",
2727
"numba": "0.53.1",
2828
"numexpr": "2.7.3",
2929
"odfpy": "1.4.1",

pandas/core/common.py

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -148,30 +148,25 @@ def is_bool_indexer(key: Any) -> bool:
148148
return False
149149

150150

151-
def cast_scalar_indexer(val, warn_float: bool = False):
151+
def cast_scalar_indexer(val):
152152
"""
153-
To avoid numpy DeprecationWarnings, cast float to integer where valid.
153+
Disallow indexing with a float key, even if that key is a round number.
154154
155155
Parameters
156156
----------
157157
val : scalar
158-
warn_float : bool, default False
159-
If True, issue deprecation warning for a float indexer.
160158
161159
Returns
162160
-------
163161
outval : scalar
164162
"""
165163
# assumes lib.is_scalar(val)
166164
if lib.is_float(val) and val.is_integer():
167-
if warn_float:
168-
warnings.warn(
169-
"Indexing with a float is deprecated, and will raise an IndexError "
170-
"in pandas 2.0. You can manually convert to an integer key instead.",
171-
FutureWarning,
172-
stacklevel=find_stack_level(),
173-
)
174-
return int(val)
165+
raise IndexError(
166+
# GH#34193
167+
"Indexing with a float is no longer supported. Manually convert "
168+
"to an integer key instead."
169+
)
175170
return val
176171

177172

pandas/core/indexers/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
check_array_indexer,
33
check_key_length,
44
check_setitem_lengths,
5-
deprecate_ndim_indexing,
5+
disallow_ndim_indexing,
66
is_empty_indexer,
77
is_list_like_indexer,
88
is_scalar_indexer,
@@ -23,7 +23,7 @@
2323
"validate_indices",
2424
"maybe_convert_indices",
2525
"length_of_indexer",
26-
"deprecate_ndim_indexing",
26+
"disallow_ndim_indexing",
2727
"unpack_1tuple",
2828
"check_key_length",
2929
"check_array_indexer",

pandas/core/indexers/utils.py

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,10 @@
77
TYPE_CHECKING,
88
Any,
99
)
10-
import warnings
1110

1211
import numpy as np
1312

1413
from pandas._typing import AnyArrayLike
15-
from pandas.util._exceptions import find_stack_level
1614

1715
from pandas.core.dtypes.common import (
1816
is_array_like,
@@ -333,22 +331,18 @@ def length_of_indexer(indexer, target=None) -> int:
333331
raise AssertionError("cannot find the length of the indexer")
334332

335333

336-
def deprecate_ndim_indexing(result, stacklevel: int = 3) -> None:
334+
def disallow_ndim_indexing(result) -> None:
337335
"""
338-
Helper function to raise the deprecation warning for multi-dimensional
339-
indexing on 1D Series/Index.
336+
Helper function to disallow multi-dimensional indexing on 1D Series/Index.
340337
341338
GH#27125 indexer like idx[:, None] expands dim, but we cannot do that
342-
and keep an index, so we currently return ndarray, which is deprecated
343-
(Deprecation GH#30588).
339+
and keep an index, so we used to return ndarray, which was deprecated
340+
in GH#30588.
344341
"""
345342
if np.ndim(result) > 1:
346-
warnings.warn(
347-
"Support for multi-dimensional indexing (e.g. `obj[:, None]`) "
348-
"is deprecated and will be removed in a future "
349-
"version. Convert to a numpy array before indexing instead.",
350-
FutureWarning,
351-
stacklevel=find_stack_level(),
343+
raise ValueError(
344+
"Multi-dimensional indexing (e.g. `obj[:, None]`) is no longer "
345+
"supported. Convert to a numpy array before indexing instead."
352346
)
353347

354348

pandas/core/indexes/base.py

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@
161161
extract_array,
162162
sanitize_array,
163163
)
164-
from pandas.core.indexers import deprecate_ndim_indexing
164+
from pandas.core.indexers import disallow_ndim_indexing
165165
from pandas.core.indexes.frozen import FrozenList
166166
from pandas.core.ops import get_op_result_name
167167
from pandas.core.ops.invalid import make_invalid_op
@@ -5213,7 +5213,7 @@ def __getitem__(self, key):
52135213

52145214
if is_integer(key) or is_float(key):
52155215
# GH#44051 exclude bool, which would return a 2d ndarray
5216-
key = com.cast_scalar_indexer(key, warn_float=True)
5216+
key = com.cast_scalar_indexer(key)
52175217
return getitem(key)
52185218

52195219
if isinstance(key, slice):
@@ -5236,15 +5236,7 @@ def __getitem__(self, key):
52365236
result = getitem(key)
52375237
# Because we ruled out integer above, we always get an arraylike here
52385238
if result.ndim > 1:
5239-
deprecate_ndim_indexing(result)
5240-
if hasattr(result, "_ndarray"):
5241-
# i.e. NDArrayBackedExtensionArray
5242-
# Unpack to ndarray for MPL compat
5243-
# error: Item "ndarray[Any, Any]" of
5244-
# "Union[ExtensionArray, ndarray[Any, Any]]"
5245-
# has no attribute "_ndarray"
5246-
return result._ndarray # type: ignore[union-attr]
5247-
return result
5239+
disallow_ndim_indexing(result)
52485240

52495241
# NB: Using _constructor._simple_new would break if MultiIndex
52505242
# didn't override __getitem__

pandas/core/indexes/multi.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2031,7 +2031,7 @@ def __reduce__(self):
20312031

20322032
def __getitem__(self, key):
20332033
if is_scalar(key):
2034-
key = com.cast_scalar_indexer(key, warn_float=True)
2034+
key = com.cast_scalar_indexer(key)
20352035

20362036
retval = []
20372037
for lev, level_codes in zip(self.levels, self.codes):

pandas/core/series.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@
123123
)
124124
from pandas.core.generic import NDFrame
125125
from pandas.core.indexers import (
126-
deprecate_ndim_indexing,
126+
disallow_ndim_indexing,
127127
unpack_1tuple,
128128
)
129129
from pandas.core.indexes.accessors import CombinedDatetimelikeProperties
@@ -1003,7 +1003,7 @@ def _get_values_tuple(self, key: tuple):
10031003
# see tests.series.timeseries.test_mpl_compat_hack
10041004
# the asarray is needed to avoid returning a 2D DatetimeArray
10051005
result = np.asarray(self._values[key])
1006-
deprecate_ndim_indexing(result, stacklevel=find_stack_level())
1006+
disallow_ndim_indexing(result)
10071007
return result
10081008

10091009
if not isinstance(self.index, MultiIndex):

0 commit comments

Comments
 (0)