Skip to content

Commit ad92aee

Browse files
chris-b1jreback
authored andcommitted
BUG: date slicing with reverse sorted index
closes #14316 Author: Chris <[email protected]> Closes #14317 from chris-b1/rev-date-slice and squashes the following commits: 04feea1 [Chris] add comment / clarity dbace2b [Chris] BUG: date slicing with rev index
1 parent b99cb7a commit ad92aee

File tree

3 files changed

+23
-4
lines changed

3 files changed

+23
-4
lines changed

doc/source/whatsnew/v0.19.0.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1526,7 +1526,7 @@ Bug Fixes
15261526
- Bug in ``.shift`` raises ``AmbiguousTimeError`` if data contains datetime near DST boundary (:issue:`13926`)
15271527
- 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`)
15281528
- Bug in ``.iloc`` when indexing with a non lex-sorted MultiIndex (:issue:`13797`)
1529-
1529+
- Bug in ``.loc`` when indexing with date strings in a reverse sorted ``DatetimeIndex`` (:issue:`14316`)
15301530

15311531
- Bug in ``Series`` comparison operators when dealing with zero dim NumPy arrays (:issue:`13006`)
15321532
- Bug in ``.combine_first`` may return incorrect ``dtype`` (:issue:`7630`, :issue:`10567`)

pandas/tests/indexing/test_indexing.py

+14-1
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ class TestIndexing(tm.TestCase):
100100
_multiprocess_can_split_ = True
101101

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

105105
def setUp(self):
106106

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

140+
dates_rev = (date_range('20130101', periods=4)
141+
.sort_values(ascending=False))
142+
self.series_ts_rev = Series(np.random.randn(4),
143+
index=dates_rev)
144+
self.frame_ts_rev = DataFrame(np.random.randn(4, 4),
145+
index=dates_rev)
146+
self.panel_ts_rev = Panel(np.random.randn(4, 4, 4),
147+
items=dates_rev)
148+
140149
self.frame_empty = DataFrame({})
141150
self.series_empty = Series({})
142151
self.panel_empty = Panel({})
@@ -1358,6 +1367,10 @@ def test_loc_getitem_label_slice(self):
13581367
'ix', slice('20130102', '20130104'),
13591368
typs=['ts'], axes=2, fails=TypeError)
13601369

1370+
# GH 14316
1371+
self.check_result('ts slice rev', 'loc', slice('20130104', '20130102'),
1372+
'indexer', [0, 1, 2], typs=['ts_rev'], axes=0)
1373+
13611374
self.check_result('mixed slice', 'loc', slice(2, 8), 'ix', slice(2, 8),
13621375
typs=['mixed'], axes=0, fails=TypeError)
13631376
self.check_result('mixed slice', 'loc', slice(2, 8), 'ix', slice(2, 8),

pandas/tseries/index.py

+8-2
Original file line numberDiff line numberDiff line change
@@ -1446,8 +1446,14 @@ def _maybe_cast_slice_bound(self, label, side, kind):
14461446
freq = getattr(self, 'freqstr',
14471447
getattr(self, 'inferred_freq', None))
14481448
_, parsed, reso = parse_time_string(label, freq)
1449-
bounds = self._parsed_string_to_bounds(reso, parsed)
1450-
return bounds[0 if side == 'left' else 1]
1449+
lower, upper = self._parsed_string_to_bounds(reso, parsed)
1450+
# lower, upper form the half-open interval:
1451+
# [parsed, parsed + 1 freq)
1452+
# because label may be passed to searchsorted
1453+
# the bounds need swapped if index is reverse sorted
1454+
if self.is_monotonic_decreasing:
1455+
return upper if side == 'left' else lower
1456+
return lower if side == 'left' else upper
14511457
else:
14521458
return label
14531459

0 commit comments

Comments
 (0)