Skip to content

Commit 4dc6785

Browse files
authored
DEPR: Index.get_loc with method (#42269)
1 parent 0469d1e commit 4dc6785

File tree

8 files changed

+61
-16
lines changed

8 files changed

+61
-16
lines changed

doc/source/whatsnew/v1.4.0.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ Other API changes
9797
Deprecations
9898
~~~~~~~~~~~~
9999
- Deprecated :meth:`Index.is_type_compatible` (:issue:`42113`)
100-
-
100+
- Deprecated ``method`` argument in :meth:`Index.get_loc`, use ``index.get_indexer([label], method=...)`` instead (:issue:`42269`)
101101

102102
.. ---------------------------------------------------------------------------
103103

pandas/core/indexes/base.py

+23-4
Original file line numberDiff line numberDiff line change
@@ -3358,6 +3358,15 @@ def get_loc(self, key, method=None, tolerance=None):
33583358
except KeyError as err:
33593359
raise KeyError(key) from err
33603360

3361+
# GH#42269
3362+
warnings.warn(
3363+
f"Passing method to {type(self).__name__}.get_loc is deprecated "
3364+
"and will raise in a future version. Use "
3365+
"index.get_indexer([item], method=...) instead",
3366+
FutureWarning,
3367+
stacklevel=2,
3368+
)
3369+
33613370
if is_scalar(key) and isna(key) and not self.hasnans:
33623371
raise KeyError(key)
33633372

@@ -4948,14 +4957,24 @@ def asof(self, label):
49484957
Traceback (most recent call last):
49494958
ValueError: index must be monotonic increasing or decreasing
49504959
"""
4960+
self._searchsorted_monotonic(label) # validate sortedness
49514961
try:
4952-
loc = self.get_loc(label, method="pad")
4953-
except KeyError:
4954-
return self._na_value
4962+
loc = self.get_loc(label)
4963+
except (KeyError, TypeError):
4964+
# KeyError -> No exact match, try for padded
4965+
# TypeError -> passed e.g. non-hashable, fall through to get
4966+
# the tested exception message
4967+
indexer = self.get_indexer([label], method="pad")
4968+
if indexer.ndim > 1 or indexer.size > 1:
4969+
raise TypeError("asof requires scalar valued input")
4970+
loc = indexer.item()
4971+
if loc == -1:
4972+
return self._na_value
49554973
else:
49564974
if isinstance(loc, slice):
49574975
loc = loc.indices(len(self))[-1]
4958-
return self[loc]
4976+
4977+
return self[loc]
49594978

49604979
def asof_locs(self, where: Index, mask: np.ndarray) -> np.ndarray:
49614980
"""

pandas/tests/indexes/datetimes/test_indexing.py

+8-2
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,7 @@ def test_take_fill_value_with_timezone(self):
422422

423423
class TestGetLoc:
424424
@pytest.mark.parametrize("method", [None, "pad", "backfill", "nearest"])
425+
@pytest.mark.filterwarnings("ignore:Passing method:FutureWarning")
425426
def test_get_loc_method_exact_match(self, method):
426427
idx = date_range("2000-01-01", periods=3)
427428
assert idx.get_loc(idx[1], method) == 1
@@ -431,6 +432,7 @@ def test_get_loc_method_exact_match(self, method):
431432
if method is not None:
432433
assert idx.get_loc(idx[1], method, tolerance=pd.Timedelta("0 days")) == 1
433434

435+
@pytest.mark.filterwarnings("ignore:Passing method:FutureWarning")
434436
def test_get_loc(self):
435437
idx = date_range("2000-01-01", periods=3)
436438

@@ -498,7 +500,8 @@ def test_get_loc(self):
498500
)
499501
msg = "cannot yet lookup inexact labels when key is a time object"
500502
with pytest.raises(NotImplementedError, match=msg):
501-
idx.get_loc(time(12, 30), method="pad")
503+
with tm.assert_produces_warning(FutureWarning, match="deprecated"):
504+
idx.get_loc(time(12, 30), method="pad")
502505

503506
def test_get_loc_time_nat(self):
504507
# GH#35114
@@ -518,7 +521,10 @@ def test_get_loc_tz_aware(self):
518521
freq="5s",
519522
)
520523
key = Timestamp("2019-12-12 10:19:25", tz="US/Eastern")
521-
result = dti.get_loc(key, method="nearest")
524+
with tm.assert_produces_warning(
525+
FutureWarning, match="deprecated", check_stacklevel=False
526+
):
527+
result = dti.get_loc(key, method="nearest")
522528
assert result == 7433
523529

524530
def test_get_loc_nat(self):

pandas/tests/indexes/numeric/test_indexing.py

+17-6
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,17 @@ class TestGetLoc:
2424
@pytest.mark.parametrize("method", [None, "pad", "backfill", "nearest"])
2525
def test_get_loc(self, method):
2626
index = Index([0, 1, 2])
27-
assert index.get_loc(1, method=method) == 1
27+
warn = None if method is None else FutureWarning
28+
29+
with tm.assert_produces_warning(warn, match="deprecated"):
30+
assert index.get_loc(1, method=method) == 1
2831

2932
if method:
30-
assert index.get_loc(1, method=method, tolerance=0) == 1
33+
with tm.assert_produces_warning(warn, match="deprecated"):
34+
assert index.get_loc(1, method=method, tolerance=0) == 1
3135

3236
@pytest.mark.parametrize("method", [None, "pad", "backfill", "nearest"])
37+
@pytest.mark.filterwarnings("ignore:Passing method:FutureWarning")
3338
def test_get_loc_raises_bad_label(self, method):
3439
index = Index([0, 1, 2])
3540
if method:
@@ -43,6 +48,7 @@ def test_get_loc_raises_bad_label(self, method):
4348
@pytest.mark.parametrize(
4449
"method,loc", [("pad", 1), ("backfill", 2), ("nearest", 1)]
4550
)
51+
@pytest.mark.filterwarnings("ignore:Passing method:FutureWarning")
4652
def test_get_loc_tolerance(self, method, loc):
4753
index = Index([0, 1, 2])
4854
assert index.get_loc(1.1, method) == loc
@@ -52,12 +58,14 @@ def test_get_loc_tolerance(self, method, loc):
5258
def test_get_loc_outside_tolerance_raises(self, method):
5359
index = Index([0, 1, 2])
5460
with pytest.raises(KeyError, match="1.1"):
55-
index.get_loc(1.1, method, tolerance=0.05)
61+
with tm.assert_produces_warning(FutureWarning, match="deprecated"):
62+
index.get_loc(1.1, method, tolerance=0.05)
5663

5764
def test_get_loc_bad_tolerance_raises(self):
5865
index = Index([0, 1, 2])
5966
with pytest.raises(ValueError, match="must be numeric"):
60-
index.get_loc(1.1, "nearest", tolerance="invalid")
67+
with tm.assert_produces_warning(FutureWarning, match="deprecated"):
68+
index.get_loc(1.1, "nearest", tolerance="invalid")
6169

6270
def test_get_loc_tolerance_no_method_raises(self):
6371
index = Index([0, 1, 2])
@@ -67,8 +75,10 @@ def test_get_loc_tolerance_no_method_raises(self):
6775
def test_get_loc_raises_missized_tolerance(self):
6876
index = Index([0, 1, 2])
6977
with pytest.raises(ValueError, match="tolerance size must match"):
70-
index.get_loc(1.1, "nearest", tolerance=[1, 1])
78+
with tm.assert_produces_warning(FutureWarning, match="deprecated"):
79+
index.get_loc(1.1, "nearest", tolerance=[1, 1])
7180

81+
@pytest.mark.filterwarnings("ignore:Passing method:FutureWarning")
7282
def test_get_loc_float64(self):
7383
idx = Float64Index([0.0, 1.0, 2.0])
7484
for method in [None, "pad", "backfill", "nearest"]:
@@ -139,7 +149,8 @@ def test_get_loc_float_index_nan_with_method(self, vals, method):
139149
# GH#39382
140150
idx = Index(vals)
141151
with pytest.raises(KeyError, match="nan"):
142-
idx.get_loc(np.nan, method=method)
152+
with tm.assert_produces_warning(FutureWarning, match="deprecated"):
153+
idx.get_loc(np.nan, method=method)
143154

144155

145156
class TestGetIndexer:

pandas/tests/indexes/object/test_indexing.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,14 @@ class TestGetLoc:
1010
def test_get_loc_raises_object_nearest(self):
1111
index = Index(["a", "c"])
1212
with pytest.raises(TypeError, match="unsupported operand type"):
13-
index.get_loc("a", method="nearest")
13+
with tm.assert_produces_warning(FutureWarning, match="deprecated"):
14+
index.get_loc("a", method="nearest")
1415

1516
def test_get_loc_raises_object_tolerance(self):
1617
index = Index(["a", "c"])
1718
with pytest.raises(TypeError, match="unsupported operand type"):
18-
index.get_loc("a", method="pad", tolerance="invalid")
19+
with tm.assert_produces_warning(FutureWarning, match="deprecated"):
20+
index.get_loc("a", method="pad", tolerance="invalid")
1921

2022

2123
class TestGetIndexer:

pandas/tests/indexes/period/test_indexing.py

+2
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,7 @@ def test_get_loc_integer(self):
339339

340340
# TODO: This method came from test_period; de-dup with version above
341341
@pytest.mark.parametrize("method", [None, "pad", "backfill", "nearest"])
342+
@pytest.mark.filterwarnings("ignore:Passing method:FutureWarning")
342343
def test_get_loc_method(self, method):
343344
idx = period_range("2000-01-01", periods=3)
344345

@@ -352,6 +353,7 @@ def test_get_loc_method(self, method):
352353
idx.get_loc(key, method=method)
353354

354355
# TODO: This method came from test_period; de-dup with version above
356+
@pytest.mark.filterwarnings("ignore:Passing method:FutureWarning")
355357
def test_get_loc3(self):
356358

357359
idx = period_range("2000-01-01", periods=5)[::2]

pandas/tests/indexes/timedeltas/test_indexing.py

+1
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ def test_timestamp_invalid_key(self, key):
8282

8383

8484
class TestGetLoc:
85+
@pytest.mark.filterwarnings("ignore:Passing method:FutureWarning")
8586
def test_get_loc(self):
8687
idx = to_timedelta(["0 days", "1 days", "2 days"])
8788

pandas/tests/test_downstream.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,11 @@ def test_xarray_cftimeindex_nearest():
5959
import xarray
6060

6161
times = xarray.cftime_range("0001", periods=2)
62-
result = times.get_loc(cftime.DatetimeGregorian(2000, 1, 1), method="nearest")
62+
key = cftime.DatetimeGregorian(2000, 1, 1)
63+
with tm.assert_produces_warning(
64+
FutureWarning, match="deprecated", check_stacklevel=False
65+
):
66+
result = times.get_loc(key, method="nearest")
6367
expected = 1
6468
assert result == expected
6569

0 commit comments

Comments
 (0)