Skip to content

Commit 1a9de7c

Browse files
dsaxtonrhshadrach
authored andcommitted
BUG: Adjust truncate for decreasing index (pandas-dev#33769)
1 parent f6609ea commit 1a9de7c

File tree

4 files changed

+38
-0
lines changed

4 files changed

+38
-0
lines changed

doc/source/whatsnew/v1.1.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -568,6 +568,7 @@ Indexing
568568
- Bug in :meth:`DatetimeIndex.insert` and :meth:`TimedeltaIndex.insert` causing index ``freq`` to be lost when setting an element into an empty :class:`Series` (:issue:33573`)
569569
- Bug in :meth:`Series.__setitem__` with an :class:`IntervalIndex` and a list-like key of integers (:issue:`33473`)
570570
- Bug in :meth:`Series.__getitem__` allowing missing labels with ``np.ndarray``, :class:`Index`, :class:`Series` indexers but not ``list``, these now all raise ``KeyError`` (:issue:`33646`)
571+
- Bug in :meth:`DataFrame.truncate` and :meth:`Series.truncate` where index was assumed to be monotone increasing (:issue:`33756`)
571572

572573
Missing
573574
^^^^^^^

pandas/core/generic.py

+3
Original file line numberDiff line numberDiff line change
@@ -9196,6 +9196,9 @@ def truncate(
91969196
if before > after:
91979197
raise ValueError(f"Truncate: {after} must be after {before}")
91989198

9199+
if ax.is_monotonic_decreasing:
9200+
before, after = after, before
9201+
91999202
slicer = [slice(None, None)] * self._AXIS_LEN
92009203
slicer[axis] = slice(before, after)
92019204
result = self.loc[tuple(slicer)]

pandas/tests/frame/methods/test_truncate.py

+17
Original file line numberDiff line numberDiff line change
@@ -87,3 +87,20 @@ def test_truncate_nonsortedindex(self):
8787
msg = "truncate requires a sorted index"
8888
with pytest.raises(ValueError, match=msg):
8989
df.truncate(before=2, after=20, axis=1)
90+
91+
@pytest.mark.parametrize(
92+
"before, after, indices",
93+
[(1, 2, [2, 1]), (None, 2, [2, 1, 0]), (1, None, [3, 2, 1])],
94+
)
95+
@pytest.mark.parametrize("klass", [pd.Int64Index, pd.DatetimeIndex])
96+
def test_truncate_decreasing_index(self, before, after, indices, klass):
97+
# https://github.com/pandas-dev/pandas/issues/33756
98+
idx = klass([3, 2, 1, 0])
99+
if klass is pd.DatetimeIndex:
100+
before = pd.Timestamp(before) if before is not None else None
101+
after = pd.Timestamp(after) if after is not None else None
102+
indices = [pd.Timestamp(i) for i in indices]
103+
values = pd.DataFrame(range(len(idx)), index=idx)
104+
result = values.truncate(before=before, after=after)
105+
expected = values.loc[indices]
106+
tm.assert_frame_equal(result, expected)

pandas/tests/series/methods/test_truncate.py

+17
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,23 @@ def test_truncate_nonsortedindex(self):
8080
with pytest.raises(ValueError, match=msg):
8181
ts.sort_values(ascending=False).truncate(before="2011-11", after="2011-12")
8282

83+
@pytest.mark.parametrize(
84+
"before, after, indices",
85+
[(1, 2, [2, 1]), (None, 2, [2, 1, 0]), (1, None, [3, 2, 1])],
86+
)
87+
@pytest.mark.parametrize("klass", [pd.Int64Index, pd.DatetimeIndex])
88+
def test_truncate_decreasing_index(self, before, after, indices, klass):
89+
# https://github.com/pandas-dev/pandas/issues/33756
90+
idx = klass([3, 2, 1, 0])
91+
if klass is pd.DatetimeIndex:
92+
before = pd.Timestamp(before) if before is not None else None
93+
after = pd.Timestamp(after) if after is not None else None
94+
indices = [pd.Timestamp(i) for i in indices]
95+
values = pd.Series(range(len(idx)), index=idx)
96+
result = values.truncate(before=before, after=after)
97+
expected = values.loc[indices]
98+
tm.assert_series_equal(result, expected)
99+
83100
def test_truncate_datetimeindex_tz(self):
84101
# GH 9243
85102
idx = date_range("4/1/2005", "4/30/2005", freq="D", tz="US/Pacific")

0 commit comments

Comments
 (0)