Skip to content

BUG: date slicing with reverse sorted index #14317

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion doc/source/whatsnew/v0.19.0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1521,7 +1521,7 @@ Bug Fixes
- Bug in ``.shift`` raises ``AmbiguousTimeError`` if data contains datetime near DST boundary (:issue:`13926`)
- Bug in ``pd.read_hdf()`` returns incorrect result when a ``DataFrame`` with a ``categorical`` column and a query which doesn't match any values (:issue:`13792`)
- Bug in ``.iloc`` when indexing with a non lex-sorted MultiIndex (:issue:`13797`)

- Bug in ``.loc`` when indexing with date strings in a reverse sorted ``DatetimeIndex`` (:issue:`14316`)

- Bug in ``Series`` comparison operators when dealing with zero dim NumPy arrays (:issue:`13006`)
- Bug in ``.combine_first`` may return incorrect ``dtype`` (:issue:`7630`, :issue:`10567`)
Expand Down
15 changes: 14 additions & 1 deletion pandas/tests/indexing/test_indexing.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ class TestIndexing(tm.TestCase):
_multiprocess_can_split_ = True

_objs = set(['series', 'frame', 'panel'])
_typs = set(['ints', 'labels', 'mixed', 'ts', 'floats', 'empty'])
_typs = set(['ints', 'labels', 'mixed', 'ts', 'floats', 'empty', 'ts_rev'])

def setUp(self):

Expand Down Expand Up @@ -137,6 +137,15 @@ def setUp(self):
self.panel_ts = Panel(np.random.randn(4, 4, 4),
items=date_range('20130101', periods=4))

dates_rev = (date_range('20130101', periods=4)
.sort_values(ascending=False))
self.series_ts_rev = Series(np.random.randn(4),
index=dates_rev)
self.frame_ts_rev = DataFrame(np.random.randn(4, 4),
index=dates_rev)
self.panel_ts_rev = Panel(np.random.randn(4, 4, 4),
items=dates_rev)

self.frame_empty = DataFrame({})
self.series_empty = Series({})
self.panel_empty = Panel({})
Expand Down Expand Up @@ -1358,6 +1367,10 @@ def test_loc_getitem_label_slice(self):
'ix', slice('20130102', '20130104'),
typs=['ts'], axes=2, fails=TypeError)

# GH 14316
self.check_result('ts slice rev', 'loc', slice('20130104', '20130102'),
'indexer', [0, 1, 2], typs=['ts_rev'], axes=0)

self.check_result('mixed slice', 'loc', slice(2, 8), 'ix', slice(2, 8),
typs=['mixed'], axes=0, fails=TypeError)
self.check_result('mixed slice', 'loc', slice(2, 8), 'ix', slice(2, 8),
Expand Down
10 changes: 8 additions & 2 deletions pandas/tseries/index.py
Original file line number Diff line number Diff line change
Expand Up @@ -1446,8 +1446,14 @@ def _maybe_cast_slice_bound(self, label, side, kind):
freq = getattr(self, 'freqstr',
getattr(self, 'inferred_freq', None))
_, parsed, reso = parse_time_string(label, freq)
bounds = self._parsed_string_to_bounds(reso, parsed)
return bounds[0 if side == 'left' else 1]
lower, upper = self._parsed_string_to_bounds(reso, parsed)
# lower, upper form the half-open interval:
# [parsed, parsed + 1 freq)
# because label may be passed to searchsorted
# the bounds need swapped if index is reverse sorted
if self.is_monotonic_decreasing:
return upper if side == 'left' else lower
return lower if side == 'left' else upper
else:
return label

Expand Down