Skip to content

Backport PR #42776 on branch 1.3.x (BUG: Incorrect variable window bounds for first row when offset cover all rows) #42929

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

Merged
Merged
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
1 change: 1 addition & 0 deletions doc/source/whatsnew/v1.3.2.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ Bug fixes
~~~~~~~~~
- Bug in :meth:`pandas.read_excel` modifies the dtypes dictionary when reading a file with duplicate columns (:issue:`42462`)
- 1D slices over extension types turn into N-dimensional slices over ExtensionArrays (:issue:`42430`)
- Fixed bug in :meth:`Series.rolling` and :meth:`DataFrame.rolling` not calculating window bounds correctly for the first row when ``center=True`` and ``window`` is an offset that covers all the rows (:issue:`42753`)
- :meth:`.Styler.hide_columns` now hides the index name header row as well as column headers (:issue:`42101`)
- Bug in de-serializing datetime indexes in PYTHONOPTIMIZED mode (:issue:`42866`)
-
Expand Down
9 changes: 4 additions & 5 deletions pandas/_libs/window/indexers.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,11 @@ def calculate_variable_window_bounds(
else:
end[0] = 0
if center:
for j in range(0, num_values + 1):
if (index[j] == index[0] + index_growth_sign * window_size / 2 and
right_closed):
end_bound = index[0] + index_growth_sign * window_size / 2
for j in range(0, num_values):
if (index[j] < end_bound) or (index[j] == end_bound and right_closed):
end[0] = j + 1
break
elif index[j] >= index[0] + index_growth_sign * window_size / 2:
elif index[j] >= end_bound:
end[0] = j
break

Expand Down
30 changes: 30 additions & 0 deletions pandas/tests/window/test_rolling.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,36 @@ def test_datetimelike_centered_selections(
tm.assert_frame_equal(result, expected, check_dtype=False)


@pytest.mark.parametrize(
"window,closed,expected",
[
("3s", "right", [3.0, 3.0, 3.0]),
("3s", "both", [3.0, 3.0, 3.0]),
("3s", "left", [3.0, 3.0, 3.0]),
("3s", "neither", [3.0, 3.0, 3.0]),
("2s", "right", [3.0, 2.0, 2.0]),
("2s", "both", [3.0, 3.0, 3.0]),
("2s", "left", [1.0, 3.0, 3.0]),
("2s", "neither", [1.0, 2.0, 2.0]),
],
)
def test_datetimelike_centered_offset_covers_all(
window, closed, expected, frame_or_series
):
# GH 42753

index = [
Timestamp("20130101 09:00:01"),
Timestamp("20130101 09:00:02"),
Timestamp("20130101 09:00:02"),
]
df = frame_or_series([1, 1, 1], index=index)

result = df.rolling(window, closed=closed, center=True).sum()
expected = frame_or_series(expected, index=index)
tm.assert_equal(result, expected)


def test_even_number_window_alignment():
# see discussion in GH 38780
s = Series(range(3), index=date_range(start="2020-01-01", freq="D", periods=3))
Expand Down