Skip to content

Commit 5c9c7ee

Browse files
committed
Correct check when slicing non-monotonic datetime indexes
The intention of pandas-dev#37819 was to deprecate (removed in pandas-dev#49607) the special case behaviour of non-monotonic datetime indexes, so that if either slice bound is not in the index, a KeyError is raised. However, the check only fired correctly for the case where the lower bound was not in the index and either the upper bound was None or it was _also_ not in the index. Correct the logic here and adapt the one test that exercises this behaviour. Closes pandas-dev#53983.
1 parent 172b7c1 commit 5c9c7ee

File tree

2 files changed

+14
-5
lines changed

2 files changed

+14
-5
lines changed

pandas/core/indexes/datetimes.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -666,18 +666,18 @@ def check_str_or_none(point) -> bool:
666666
return Index.slice_indexer(self, start, end, step)
667667

668668
mask = np.array(True)
669-
raise_mask = np.array(True)
669+
in_index = True
670670
if start is not None:
671671
start_casted = self._maybe_cast_slice_bound(start, "left")
672672
mask = start_casted <= self
673-
raise_mask = start_casted == self
673+
in_index &= (start_casted == self).any()
674674

675675
if end is not None:
676676
end_casted = self._maybe_cast_slice_bound(end, "right")
677677
mask = (self <= end_casted) & mask
678-
raise_mask = (end_casted == self) | raise_mask
678+
in_index &= (end_casted == self).any()
679679

680-
if not raise_mask.any():
680+
if not in_index:
681681
raise KeyError(
682682
"Value based partial slicing on non-monotonic DatetimeIndexes "
683683
"with non-existing keys is not allowed.",

pandas/tests/indexing/test_partial.py

+10-1
Original file line numberDiff line numberDiff line change
@@ -664,5 +664,14 @@ def test_slice_irregular_datetime_index_with_nan(self):
664664
index = pd.to_datetime(["2012-01-01", "2012-01-02", "2012-01-03", None])
665665
df = DataFrame(range(len(index)), index=index)
666666
expected = DataFrame(range(len(index[:3])), index=index[:3])
667-
result = df["2012-01-01":"2012-01-04"]
667+
with pytest.raises(KeyError):
668+
# Upper bound is not in index (which is unordered)
669+
# GH53983
670+
# GH37819
671+
df["2012-01-01":"2012-01-04"]
672+
# Need this precision for right bound since the right slice
673+
# bound is "rounded" up to the largest timepoint smaller than
674+
# the next "resolution"-step of the provided point.
675+
# e.g. 2012-01-03 is rounded up to 2012-01-04 - 1ns
676+
result = df["2012-01-01":"2012-01-03 00:00:00.000000000"]
668677
tm.assert_frame_equal(result, expected)

0 commit comments

Comments
 (0)