From dcd38f0b91df3d5ef17c046c16e4a35ccc9213ea Mon Sep 17 00:00:00 2001 From: Tom Augspurger Date: Wed, 31 May 2017 11:34:36 -0500 Subject: [PATCH] BUG: Fixed partial slicing on monotonic index with dupes Fixed an edge case in partial string indexing where we would incorrectly flip the endpoint on a slice, since we checked for monotonicity when we needed strict monotonicity. Closes https://github.com/pandas-dev/pandas/issues/16515 xref https://github.com/dask/dask/issues/2389 --- doc/source/whatsnew/v0.20.2.txt | 2 +- pandas/core/indexes/datetimes.py | 2 +- pandas/tests/indexes/datetimes/test_datetime.py | 7 +++++++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/doc/source/whatsnew/v0.20.2.txt b/doc/source/whatsnew/v0.20.2.txt index 13435b2ba428b..44ad6eeab9d98 100644 --- a/doc/source/whatsnew/v0.20.2.txt +++ b/doc/source/whatsnew/v0.20.2.txt @@ -63,7 +63,7 @@ Indexing ^^^^^^^^ - Bug in ``DataFrame.reset_index(level=)`` with single level index (:issue:`16263`) - +- Bug in partial string indexing with a monotonic, but not strictly-monotonic, index incorrectly reversing the slice bounds (:issue:`16515`) I/O ^^^ diff --git a/pandas/core/indexes/datetimes.py b/pandas/core/indexes/datetimes.py index ec678b1577d81..60560374cd420 100644 --- a/pandas/core/indexes/datetimes.py +++ b/pandas/core/indexes/datetimes.py @@ -1472,7 +1472,7 @@ def _maybe_cast_slice_bound(self, label, side, kind): # the bounds need swapped if index is reverse sorted and has a # length > 1 (is_monotonic_decreasing gives True for empty # and length 1 index) - if self.is_monotonic_decreasing and len(self) > 1: + if self.is_strictly_monotonic_decreasing and len(self) > 1: return upper if side == 'left' else lower return lower if side == 'left' else upper else: diff --git a/pandas/tests/indexes/datetimes/test_datetime.py b/pandas/tests/indexes/datetimes/test_datetime.py index 6cba7e17abf8e..f99dcee9e5c8a 100644 --- a/pandas/tests/indexes/datetimes/test_datetime.py +++ b/pandas/tests/indexes/datetimes/test_datetime.py @@ -771,3 +771,10 @@ def test_slice_bounds_empty(self): left = empty_idx._maybe_cast_slice_bound('2015-01-02', 'left', 'loc') exp = Timestamp('2015-01-02 00:00:00') assert left == exp + + def test_slice_duplicate_monotonic(self): + # https://github.com/pandas-dev/pandas/issues/16515 + idx = pd.DatetimeIndex(['2017', '2017']) + result = idx._maybe_cast_slice_bound('2017-01-01', 'left', 'loc') + expected = Timestamp('2017-01-01') + assert result == expected