Skip to content

Commit d30aeeb

Browse files
authored
fixed rolling for a decreasing index, added a test for that (pandas-dev#43928)
1 parent 9f2cb73 commit d30aeeb

File tree

3 files changed

+38
-2
lines changed

3 files changed

+38
-2
lines changed

doc/source/whatsnew/v1.4.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,7 @@ Groupby/resample/rolling
502502
- Bug in :meth:`DataFrame.groupby.rolling` when specifying ``on`` and calling ``__getitem__`` would subsequently return incorrect results (:issue:`43355`)
503503
- Bug in :meth:`GroupBy.apply` with time-based :class:`Grouper` objects incorrectly raising ``ValueError`` in corner cases where the grouping vector contains a ``NaT`` (:issue:`43500`, :issue:`43515`)
504504
- Bug in :meth:`GroupBy.mean` failing with ``complex`` dtype (:issue:`43701`)
505+
- Fixed bug in :meth:`Series.rolling` and :meth:`DataFrame.rolling` not calculating window bounds correctly for the first row when ``center=True`` and index is decreasing (:issue:`43927`)
505506

506507
Reshaping
507508
^^^^^^^^^

pandas/_libs/window/indexers.pyx

+4-2
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,11 @@ def calculate_variable_window_bounds(
8181
if center:
8282
end_bound = index[0] + index_growth_sign * window_size / 2
8383
for j in range(0, num_values):
84-
if (index[j] < end_bound) or (index[j] == end_bound and right_closed):
84+
if (index[j] - end_bound) * index_growth_sign < 0:
8585
end[0] = j + 1
86-
elif index[j] >= end_bound:
86+
elif (index[j] - end_bound) * index_growth_sign == 0 and right_closed:
87+
end[0] = j + 1
88+
elif (index[j] - end_bound) * index_growth_sign >= 0:
8789
end[0] = j
8890
break
8991

pandas/tests/window/test_rolling.py

+33
Original file line numberDiff line numberDiff line change
@@ -1210,6 +1210,39 @@ def test_rolling_decreasing_indices(method):
12101210
assert np.abs(decreasing.values[::-1][:-4] - increasing.values[4:]).max() < 1e-12
12111211

12121212

1213+
@pytest.mark.parametrize(
1214+
"window,closed,expected",
1215+
[
1216+
("2s", "right", [1.0, 3.0, 5.0, 3.0]),
1217+
("2s", "left", [0.0, 1.0, 3.0, 5.0]),
1218+
("2s", "both", [1.0, 3.0, 6.0, 5.0]),
1219+
("2s", "neither", [0.0, 1.0, 2.0, 3.0]),
1220+
("3s", "right", [1.0, 3.0, 6.0, 5.0]),
1221+
("3s", "left", [1.0, 3.0, 6.0, 5.0]),
1222+
("3s", "both", [1.0, 3.0, 6.0, 5.0]),
1223+
("3s", "neither", [1.0, 3.0, 6.0, 5.0]),
1224+
],
1225+
)
1226+
def test_rolling_decreasing_indices_centered(window, closed, expected, frame_or_series):
1227+
"""
1228+
Ensure that a symmetrical inverted index return same result as non-inverted.
1229+
"""
1230+
# GH 43927
1231+
1232+
index = date_range("2020", periods=4, freq="1s")
1233+
df_inc = frame_or_series(range(4), index=index)
1234+
df_dec = frame_or_series(range(4), index=index[::-1])
1235+
1236+
expected_inc = frame_or_series(expected, index=index)
1237+
expected_dec = frame_or_series(expected, index=index[::-1])
1238+
1239+
result_inc = df_inc.rolling(window, closed=closed, center=True).sum()
1240+
result_dec = df_dec.rolling(window, closed=closed, center=True).sum()
1241+
1242+
tm.assert_equal(result_inc, expected_inc)
1243+
tm.assert_equal(result_dec, expected_dec)
1244+
1245+
12131246
@pytest.mark.parametrize(
12141247
"method,expected",
12151248
[

0 commit comments

Comments
 (0)