Skip to content

Commit 9694eb1

Browse files
natmokvalrhshadrachjorisvandenbossche
authored
ENH: clarify error message when getting slice bounds for a non-monotonic index without specifying the label (#63397)
Co-authored-by: Richard Shadrach <[email protected]> Co-authored-by: Joris Van den Bossche <[email protected]>
1 parent 910baf5 commit 9694eb1

File tree

5 files changed

+22
-9
lines changed

5 files changed

+22
-9
lines changed

pandas/core/indexes/base.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6865,12 +6865,15 @@ def get_slice_bound(self, label, side: Literal["left", "right"]) -> int:
68656865
# we need to look up the label
68666866
try:
68676867
slc = self.get_loc(label)
6868-
except KeyError as err:
6868+
except KeyError:
68696869
try:
68706870
return self._searchsorted_monotonic(label, side)
68716871
except ValueError:
6872-
# raise the original KeyError
6873-
raise err from None
6872+
raise KeyError(
6873+
f"Cannot get {side} slice bound for non-monotonic index "
6874+
f"with a missing label {original_label!r}. "
6875+
"Either sort the index or specify an existing label."
6876+
) from None
68746877

68756878
if isinstance(slc, np.ndarray):
68766879
# get_loc may return a boolean array, which

pandas/tests/frame/indexing/test_indexing.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -564,9 +564,10 @@ def test_getitem_setitem_integer_slice_keyerrors(self):
564564

565565
# non-monotonic, raise KeyError
566566
df2 = df.iloc[list(range(5)) + list(range(5, 10))[::-1]]
567-
with pytest.raises(KeyError, match=r"^3$"):
567+
msg = "non-monotonic index with a missing label 3"
568+
with pytest.raises(KeyError, match=msg):
568569
df2.loc[3:11]
569-
with pytest.raises(KeyError, match=r"^3$"):
570+
with pytest.raises(KeyError, match=msg):
570571
df2.loc[3:11] = 0
571572

572573
def test_fancy_getitem_slice_mixed(self, float_frame, float_string_frame):

pandas/tests/indexes/numeric/test_indexing.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -600,10 +600,11 @@ def test_slice_locs_na(self):
600600

601601
def test_slice_locs_na_raises(self):
602602
index = Index([np.nan, 1, 2])
603-
with pytest.raises(KeyError, match="1.5"):
603+
msg = "non-monotonic index with a missing label 1.5"
604+
with pytest.raises(KeyError, match=msg):
604605
index.slice_locs(start=1.5)
605606

606-
with pytest.raises(KeyError, match="1.5"):
607+
with pytest.raises(KeyError, match=msg):
607608
index.slice_locs(end=1.5)
608609

609610

pandas/tests/indexing/test_loc.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3162,9 +3162,10 @@ def test_loc_getitem_setitem_integer_slice_keyerrors(self):
31623162

31633163
# non-monotonic, raise KeyError
31643164
s2 = ser.iloc[list(range(5)) + list(range(9, 4, -1))]
3165-
with pytest.raises(KeyError, match=r"^3$"):
3165+
msg = "non-monotonic index with a missing label 3"
3166+
with pytest.raises(KeyError, match=msg):
31663167
s2.loc[3:11]
3167-
with pytest.raises(KeyError, match=r"^3$"):
3168+
with pytest.raises(KeyError, match=msg):
31683169
s2.loc[3:11] = 0
31693170

31703171
def test_loc_getitem_iterator(self, string_series):

pandas/tests/series/indexing/test_indexing.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,13 @@ def test_setitem_empty_indexer(indexer, val):
404404
tm.assert_frame_equal(df, expected)
405405

406406

407+
def test_loc_non_monotonic_index_with_a_missing_label():
408+
msg = "Cannot get left slice bound for non-monotonic index with a missing label 4"
409+
ser = Series([3, 6, 7, 6], index=[3, 8, 7, 6])
410+
with pytest.raises(KeyError, match=msg):
411+
ser.loc[4:7]
412+
413+
407414
class TestDeprecatedIndexers:
408415
@pytest.mark.parametrize("key", [{1}, {1: 1}])
409416
def test_getitem_dict_and_set_deprecated(self, key):

0 commit comments

Comments
 (0)