Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 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/v1.2.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ Groupby/resample/rolling
- Bug in :meth:`DataFrameGroupby.tshift` failing to raise ``ValueError`` when a frequency cannot be inferred for the index of a group (:issue:`35937`)
- Bug in :meth:`DataFrame.groupby` does not always maintain column index name for ``any``, ``all``, ``bfill``, ``ffill``, ``shift`` (:issue:`29764`)
- Bug in :meth:`DataFrameGroupBy.apply` raising error with ``np.nan`` group(s) when ``dropna=False`` (:issue:`35889`)
-
- Bug in :meth:`Rolling.sum()` returned wrong values when dtypes where mixed between float and integer and axis was equal to one (:issue:`20649`, :issue:`35596`)

Reshaping
^^^^^^^^^
Expand Down
6 changes: 5 additions & 1 deletion pandas/core/window/rolling.py
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,11 @@ def _create_data(self, obj: FrameOrSeries) -> FrameOrSeries:
if self.on is not None and not isinstance(self.on, Index):
if obj.ndim == 2:
obj = obj.reindex(columns=obj.columns.difference([self.on]), copy=False)

if self.axis == 1:
# GH: 20649 in case of mixed dtype and axis=1 we have to convert everything
# to float to calculate the complete row at once
obj = obj.astype("float64", copy=False)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add a comment with the issue number and a small explanation on why we are doing this?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cc @jbrockmendel FYI

obj._mgr = obj._mgr.consolidate()
return obj

def _gotitem(self, key, ndim, subset=None):
Expand Down
35 changes: 35 additions & 0 deletions pandas/tests/window/test_rolling.py
Original file line number Diff line number Diff line change
Expand Up @@ -771,3 +771,38 @@ def test_rolling_numerical_too_large_numbers():
index=dates,
)
tm.assert_series_equal(result, expected)


@pytest.mark.parametrize(
("func", "value"),
[("sum", 2.0), ("max", 1.0), ("min", 1.0), ("mean", 1.0), ("median", 1.0)],
)
def test_rolling_mixed_dtypes_axis_1(func, value):
# GH: 20649
df = pd.DataFrame(1, index=[1, 2], columns=["a", "b", "c"])
df["c"] = 1.0
result = getattr(df.rolling(window=2, min_periods=1, axis=1), func)()
expected = pd.DataFrame(
{"a": [1.0, 1.0], "b": [value, value], "c": [value, value]}, index=[1, 2]
)
tm.assert_frame_equal(result, expected)


def test_rolling_axis_one_with_nan():
# GH: 35596
df = pd.DataFrame(
[
[0, 1, 2, 4, np.nan, np.nan, np.nan],
[0, 1, 2, np.nan, np.nan, np.nan, np.nan],
[0, 2, 2, np.nan, 2, np.nan, 1],
]
)
result = df.rolling(window=7, min_periods=1, axis="columns").sum()
expected = pd.DataFrame(
[
[0.0, 1.0, 3.0, 7.0, 7.0, 7.0, 7.0],
[0.0, 1.0, 3.0, 3.0, 3.0, 3.0, 3.0],
[0.0, 2.0, 4.0, 4.0, 6.0, 6.0, 7.0],
]
)
tm.assert_frame_equal(result, expected)