From 11d702d1d48d622498075eb7405354a77e4c51fd Mon Sep 17 00:00:00 2001 From: benHeid Date: Fri, 9 Jul 2021 14:48:26 +0200 Subject: [PATCH 1/9] BUG: Mitigate division with zero in roll_var --- pandas/_libs/window/aggregations.pyx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pandas/_libs/window/aggregations.pyx b/pandas/_libs/window/aggregations.pyx index 3d3a19a1c7a40..a4b83695f57b6 100644 --- a/pandas/_libs/window/aggregations.pyx +++ b/pandas/_libs/window/aggregations.pyx @@ -310,7 +310,10 @@ cdef inline void add_var(float64_t val, float64_t *nobs, float64_t *mean_x, t = y - mean_x[0] compensation[0] = t + mean_x[0] - y delta = t - mean_x[0] = mean_x[0] + delta / nobs[0] + if nobs[0]: + mean_x[0] = mean_x[0] + delta / nobs[0] + else: + mean_x[0] = 0 ssqdm_x[0] = ssqdm_x[0] + (val - prev_mean) * (val - mean_x[0]) From 113e35b99168b3f30b93169d5b03514bdb5b52ff Mon Sep 17 00:00:00 2001 From: benHeid Date: Mon, 12 Jul 2021 10:20:36 +0200 Subject: [PATCH 2/9] Add tests with different rolling_arguments --- pandas/tests/window/test_groupby.py | 60 ++++++++++++++++++----------- 1 file changed, 37 insertions(+), 23 deletions(-) diff --git a/pandas/tests/window/test_groupby.py b/pandas/tests/window/test_groupby.py index 5d7fc50620ef8..27a5b627db6af 100644 --- a/pandas/tests/window/test_groupby.py +++ b/pandas/tests/window/test_groupby.py @@ -20,7 +20,6 @@ def setup_method(self): self.frame = DataFrame({"A": [1] * 20 + [2] * 12 + [3] * 8, "B": np.arange(40)}) def test_mutated(self): - msg = r"groupby\(\) got an unexpected keyword argument 'foo'" with pytest.raises(TypeError, match=msg): self.frame.groupby("A", foo=1) @@ -49,7 +48,6 @@ def test_getitem(self): tm.assert_series_equal(result, expected) def test_getitem_multiple(self): - # GH 13174 g = self.frame.groupby("A") r = g.rolling(2, min_periods=0) @@ -275,8 +273,8 @@ def test_groupby_rolling_center_on(self): ) result = ( df.groupby("gb") - .rolling(6, on="Date", center=True, min_periods=1) - .value.mean() + .rolling(6, on="Date", center=True, min_periods=1) + .value.mean() ) expected = Series( [1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 7.0, 7.5, 7.5, 7.5], @@ -307,8 +305,8 @@ def test_groupby_rolling_center_min_periods(self, min_periods): window_size = 5 result = ( df.groupby("group") - .rolling(window_size, center=True, min_periods=min_periods) - .mean() + .rolling(window_size, center=True, min_periods=min_periods) + .mean() ) result = result.reset_index()[["group", "data"]] @@ -317,8 +315,8 @@ def test_groupby_rolling_center_min_periods(self, min_periods): num_nans = max(0, min_periods - 3) # For window_size of 5 nans = [np.nan] * num_nans - grp_A_expected = nans + grp_A_mean[num_nans : 10 - num_nans] + nans - grp_B_expected = nans + grp_B_mean[num_nans : 10 - num_nans] + nans + grp_A_expected = nans + grp_A_mean[num_nans: 10 - num_nans] + nans + grp_B_expected = nans + grp_B_mean[num_nans: 10 - num_nans] + nans expected = DataFrame( {"group": ["A"] * 10 + ["B"] * 10, "data": grp_A_expected + grp_B_expected} @@ -355,7 +353,7 @@ def test_groupby_rolling_custom_indexer(self): # GH 35557 class SimpleIndexer(BaseIndexer): def get_window_bounds( - self, num_values=0, min_periods=None, center=None, closed=None + self, num_values=0, min_periods=None, center=None, closed=None ): min_periods = self.window_size if min_periods is None else 0 end = np.arange(num_values, dtype=np.int64) + 1 @@ -368,8 +366,8 @@ def get_window_bounds( ) result = ( df.groupby(df.index) - .rolling(SimpleIndexer(window_size=3), min_periods=1) - .sum() + .rolling(SimpleIndexer(window_size=3), min_periods=1) + .sum() ) expected = df.groupby(df.index).rolling(window=3, min_periods=1).sum() tm.assert_frame_equal(result, expected) @@ -411,8 +409,8 @@ def test_groupby_subset_rolling_subset_with_closed(self): result = ( df.groupby("group")[["column1", "date"]] - .rolling("1D", on="date", closed="left")["column1"] - .sum() + .rolling("1D", on="date", closed="left")["column1"] + .sum() ) expected = Series( [np.nan, 0.0, 2.0, np.nan, 1.0, 4.0], @@ -506,9 +504,9 @@ def test_groupby_rolling_no_sort(self): # GH 36889 result = ( DataFrame({"foo": [2, 1], "bar": [2, 1]}) - .groupby("foo", sort=False) - .rolling(1) - .min() + .groupby("foo", sort=False) + .rolling(1) + .min() ) expected = DataFrame( np.array([[2.0, 2.0], [1.0, 1.0]]), @@ -531,8 +529,8 @@ def test_groupby_rolling_count_closed_on(self): ) result = ( df.groupby("group") - .rolling("3d", on="date", closed="left")["column1"] - .count() + .rolling("3d", on="date", closed="left")["column1"] + .count() ) expected = Series( [np.nan, 1.0, 1.0, np.nan, 1.0, 1.0], @@ -695,6 +693,22 @@ def test_groupby_rolling_object_doesnt_affect_groupby_apply(self): assert not g.mutated assert not g.grouper.mutated + @pytest.mark.parametrize( + ("window", "min_periods", "closed", "expected"), [ + (2, 0, "left", [None, 0.0, 1.0, 1.0, None, 0.0, 1.0, 1.0]), + (2, 2, "left", [None, None, 1.0, 1.0, None, None, 1.0, 1.0]), + (4, 4, "left", [None, None, None, None, None, None, None, None]), + (4, 4, "right", [None, None, None, 5.0, None, None, None, 5.0]) + ]) + def test_groupby_rolling_var(self, window, min_periods, closed, expected): + df = DataFrame([1, 2, 3, 4, 5, 6, 7, 8]) + result = df.groupby([1, 2, 1, 2, 1, 2, 1, 2]).rolling(window=window, min_periods=min_periods, + closed=closed).var(0) + expected_result = DataFrame(np.array(expected, dtype="float64"), index=MultiIndex(levels=[[1, 2], [0, 1, 2, 3, 4, 5, 6, 7]], + codes=[[0, 0, 0, 0, 1, 1, 1, 1], + [0, 2, 4, 6, 1, 3, 5, 7]])) + tm.assert_frame_equal(result, expected_result) + @pytest.mark.parametrize( "columns", [MultiIndex.from_tuples([("A", ""), ("B", "C")]), ["A", "B"]] ) @@ -970,9 +984,9 @@ def test_times_vs_apply(self, times_frame): result = times_frame.groupby("A").ewm(halflife=halflife, times="C").mean() expected = ( times_frame.groupby("A") - .apply(lambda x: x.ewm(halflife=halflife, times="C").mean()) - .iloc[[0, 3, 6, 9, 1, 4, 7, 2, 5, 8]] - .reset_index(drop=True) + .apply(lambda x: x.ewm(halflife=halflife, times="C").mean()) + .iloc[[0, 3, 6, 9, 1, 4, 7, 2, 5, 8]] + .reset_index(drop=True) ) tm.assert_frame_equal(result.reset_index(drop=True), expected) @@ -982,7 +996,7 @@ def test_times_array(self, times_frame): result = times_frame.groupby("A").ewm(halflife=halflife, times="C").mean() expected = ( times_frame.groupby("A") - .ewm(halflife=halflife, times=times_frame["C"].values) - .mean() + .ewm(halflife=halflife, times=times_frame["C"].values) + .mean() ) tm.assert_frame_equal(result, expected) From 030766522fd3d8572941f59843f0b75fc305cdad Mon Sep 17 00:00:00 2001 From: benHeid Date: Mon, 12 Jul 2021 14:09:07 +0200 Subject: [PATCH 3/9] Fix linting errors (Line to long) --- pandas/tests/window/test_groupby.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/pandas/tests/window/test_groupby.py b/pandas/tests/window/test_groupby.py index 27a5b627db6af..251fc4cd6eee6 100644 --- a/pandas/tests/window/test_groupby.py +++ b/pandas/tests/window/test_groupby.py @@ -702,11 +702,14 @@ def test_groupby_rolling_object_doesnt_affect_groupby_apply(self): ]) def test_groupby_rolling_var(self, window, min_periods, closed, expected): df = DataFrame([1, 2, 3, 4, 5, 6, 7, 8]) - result = df.groupby([1, 2, 1, 2, 1, 2, 1, 2]).rolling(window=window, min_periods=min_periods, + result = df.groupby([1, 2, 1, 2, 1, 2, 1, 2]).rolling(window=window, + min_periods=min_periods, closed=closed).var(0) - expected_result = DataFrame(np.array(expected, dtype="float64"), index=MultiIndex(levels=[[1, 2], [0, 1, 2, 3, 4, 5, 6, 7]], - codes=[[0, 0, 0, 0, 1, 1, 1, 1], - [0, 2, 4, 6, 1, 3, 5, 7]])) + expected_result = DataFrame(np.array(expected, dtype="float64"), + index=MultiIndex(levels=[[1, 2], + [0, 1, 2, 3, 4, 5, 6, 7]], + codes=[[0, 0, 0, 0, 1, 1, 1, 1], + [0, 2, 4, 6, 1, 3, 5, 7]])) tm.assert_frame_equal(result, expected_result) @pytest.mark.parametrize( From 6ac50a5a92ee2d9820ee314fbd835cc53fd23c9c Mon Sep 17 00:00:00 2001 From: benHeid Date: Mon, 12 Jul 2021 15:19:11 +0200 Subject: [PATCH 4/9] Remove autoformatted changes. --- pandas/tests/window/test_groupby.py | 53 ++++++++++++++--------------- 1 file changed, 25 insertions(+), 28 deletions(-) diff --git a/pandas/tests/window/test_groupby.py b/pandas/tests/window/test_groupby.py index 251fc4cd6eee6..a67a6c4a6c2cc 100644 --- a/pandas/tests/window/test_groupby.py +++ b/pandas/tests/window/test_groupby.py @@ -20,6 +20,7 @@ def setup_method(self): self.frame = DataFrame({"A": [1] * 20 + [2] * 12 + [3] * 8, "B": np.arange(40)}) def test_mutated(self): + msg = r"groupby\(\) got an unexpected keyword argument 'foo'" with pytest.raises(TypeError, match=msg): self.frame.groupby("A", foo=1) @@ -48,6 +49,7 @@ def test_getitem(self): tm.assert_series_equal(result, expected) def test_getitem_multiple(self): + # GH 13174 g = self.frame.groupby("A") r = g.rolling(2, min_periods=0) @@ -273,8 +275,8 @@ def test_groupby_rolling_center_on(self): ) result = ( df.groupby("gb") - .rolling(6, on="Date", center=True, min_periods=1) - .value.mean() + .rolling(6, on="Date", center=True, min_periods=1) + .value.mean() ) expected = Series( [1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 7.0, 7.5, 7.5, 7.5], @@ -305,8 +307,8 @@ def test_groupby_rolling_center_min_periods(self, min_periods): window_size = 5 result = ( df.groupby("group") - .rolling(window_size, center=True, min_periods=min_periods) - .mean() + .rolling(window_size, center=True, min_periods=min_periods) + .mean() ) result = result.reset_index()[["group", "data"]] @@ -315,8 +317,8 @@ def test_groupby_rolling_center_min_periods(self, min_periods): num_nans = max(0, min_periods - 3) # For window_size of 5 nans = [np.nan] * num_nans - grp_A_expected = nans + grp_A_mean[num_nans: 10 - num_nans] + nans - grp_B_expected = nans + grp_B_mean[num_nans: 10 - num_nans] + nans + grp_A_expected = nans + grp_A_mean[num_nans : 10 - num_nans] + nans + grp_B_expected = nans + grp_B_mean[num_nans : 10 - num_nans] + nans expected = DataFrame( {"group": ["A"] * 10 + ["B"] * 10, "data": grp_A_expected + grp_B_expected} @@ -353,7 +355,7 @@ def test_groupby_rolling_custom_indexer(self): # GH 35557 class SimpleIndexer(BaseIndexer): def get_window_bounds( - self, num_values=0, min_periods=None, center=None, closed=None + self, num_values=0, min_periods=None, center=None, closed=None ): min_periods = self.window_size if min_periods is None else 0 end = np.arange(num_values, dtype=np.int64) + 1 @@ -366,8 +368,8 @@ def get_window_bounds( ) result = ( df.groupby(df.index) - .rolling(SimpleIndexer(window_size=3), min_periods=1) - .sum() + .rolling(SimpleIndexer(window_size=3), min_periods=1) + .sum() ) expected = df.groupby(df.index).rolling(window=3, min_periods=1).sum() tm.assert_frame_equal(result, expected) @@ -409,8 +411,8 @@ def test_groupby_subset_rolling_subset_with_closed(self): result = ( df.groupby("group")[["column1", "date"]] - .rolling("1D", on="date", closed="left")["column1"] - .sum() + .rolling("1D", on="date", closed="left")["column1"] + .sum() ) expected = Series( [np.nan, 0.0, 2.0, np.nan, 1.0, 4.0], @@ -504,9 +506,9 @@ def test_groupby_rolling_no_sort(self): # GH 36889 result = ( DataFrame({"foo": [2, 1], "bar": [2, 1]}) - .groupby("foo", sort=False) - .rolling(1) - .min() + .groupby("foo", sort=False) + .rolling(1) + .min() ) expected = DataFrame( np.array([[2.0, 2.0], [1.0, 1.0]]), @@ -529,8 +531,8 @@ def test_groupby_rolling_count_closed_on(self): ) result = ( df.groupby("group") - .rolling("3d", on="date", closed="left")["column1"] - .count() + .rolling("3d", on="date", closed="left")["column1"] + .count() ) expected = Series( [np.nan, 1.0, 1.0, np.nan, 1.0, 1.0], @@ -693,13 +695,6 @@ def test_groupby_rolling_object_doesnt_affect_groupby_apply(self): assert not g.mutated assert not g.grouper.mutated - @pytest.mark.parametrize( - ("window", "min_periods", "closed", "expected"), [ - (2, 0, "left", [None, 0.0, 1.0, 1.0, None, 0.0, 1.0, 1.0]), - (2, 2, "left", [None, None, 1.0, 1.0, None, None, 1.0, 1.0]), - (4, 4, "left", [None, None, None, None, None, None, None, None]), - (4, 4, "right", [None, None, None, 5.0, None, None, None, 5.0]) - ]) def test_groupby_rolling_var(self, window, min_periods, closed, expected): df = DataFrame([1, 2, 3, 4, 5, 6, 7, 8]) result = df.groupby([1, 2, 1, 2, 1, 2, 1, 2]).rolling(window=window, @@ -712,6 +707,8 @@ def test_groupby_rolling_var(self, window, min_periods, closed, expected): [0, 2, 4, 6, 1, 3, 5, 7]])) tm.assert_frame_equal(result, expected_result) + + @pytest.mark.parametrize( "columns", [MultiIndex.from_tuples([("A", ""), ("B", "C")]), ["A", "B"]] ) @@ -987,9 +984,9 @@ def test_times_vs_apply(self, times_frame): result = times_frame.groupby("A").ewm(halflife=halflife, times="C").mean() expected = ( times_frame.groupby("A") - .apply(lambda x: x.ewm(halflife=halflife, times="C").mean()) - .iloc[[0, 3, 6, 9, 1, 4, 7, 2, 5, 8]] - .reset_index(drop=True) + .apply(lambda x: x.ewm(halflife=halflife, times="C").mean()) + .iloc[[0, 3, 6, 9, 1, 4, 7, 2, 5, 8]] + .reset_index(drop=True) ) tm.assert_frame_equal(result.reset_index(drop=True), expected) @@ -999,7 +996,7 @@ def test_times_array(self, times_frame): result = times_frame.groupby("A").ewm(halflife=halflife, times="C").mean() expected = ( times_frame.groupby("A") - .ewm(halflife=halflife, times=times_frame["C"].values) - .mean() + .ewm(halflife=halflife, times=times_frame["C"].values) + .mean() ) tm.assert_frame_equal(result, expected) From ba6fa38017c278ffa6416c2986357166fc00fb60 Mon Sep 17 00:00:00 2001 From: benHeid Date: Mon, 12 Jul 2021 15:21:58 +0200 Subject: [PATCH 5/9] Update parameters --- pandas/tests/window/test_groupby.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/pandas/tests/window/test_groupby.py b/pandas/tests/window/test_groupby.py index a67a6c4a6c2cc..2570ecab15a19 100644 --- a/pandas/tests/window/test_groupby.py +++ b/pandas/tests/window/test_groupby.py @@ -695,6 +695,13 @@ def test_groupby_rolling_object_doesnt_affect_groupby_apply(self): assert not g.mutated assert not g.grouper.mutated + @pytest.mark.parametrize( + ("window", "min_periods", "closed", "expected"), [ + (2, 0, "left", [None, 0.0, 1.0, 1.0, None, 0.0, 1.0, 1.0]), + (2, 2, "left", [None, None, 1.0, 1.0, None, None, 1.0, 1.0]), + (4, 4, "left", [None, None, None, None, None, None, None, None]), + (4, 4, "right", [None, None, None, 5.0, None, None, None, 5.0]) + ]) def test_groupby_rolling_var(self, window, min_periods, closed, expected): df = DataFrame([1, 2, 3, 4, 5, 6, 7, 8]) result = df.groupby([1, 2, 1, 2, 1, 2, 1, 2]).rolling(window=window, @@ -984,9 +991,9 @@ def test_times_vs_apply(self, times_frame): result = times_frame.groupby("A").ewm(halflife=halflife, times="C").mean() expected = ( times_frame.groupby("A") - .apply(lambda x: x.ewm(halflife=halflife, times="C").mean()) - .iloc[[0, 3, 6, 9, 1, 4, 7, 2, 5, 8]] - .reset_index(drop=True) + .apply(lambda x: x.ewm(halflife=halflife, times="C").mean()) + .iloc[[0, 3, 6, 9, 1, 4, 7, 2, 5, 8]] + .reset_index(drop=True) ) tm.assert_frame_equal(result.reset_index(drop=True), expected) @@ -996,7 +1003,7 @@ def test_times_array(self, times_frame): result = times_frame.groupby("A").ewm(halflife=halflife, times="C").mean() expected = ( times_frame.groupby("A") - .ewm(halflife=halflife, times=times_frame["C"].values) - .mean() + .ewm(halflife=halflife, times=times_frame["C"].values) + .mean() ) tm.assert_frame_equal(result, expected) From 2f0085e848e65011cf0a444eeb5eb4304663582b Mon Sep 17 00:00:00 2001 From: benHeid Date: Mon, 12 Jul 2021 15:23:07 +0200 Subject: [PATCH 6/9] Remove autoformatted changes again.. --- pandas/tests/window/test_groupby.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pandas/tests/window/test_groupby.py b/pandas/tests/window/test_groupby.py index 2570ecab15a19..47b3ce03c363b 100644 --- a/pandas/tests/window/test_groupby.py +++ b/pandas/tests/window/test_groupby.py @@ -991,9 +991,9 @@ def test_times_vs_apply(self, times_frame): result = times_frame.groupby("A").ewm(halflife=halflife, times="C").mean() expected = ( times_frame.groupby("A") - .apply(lambda x: x.ewm(halflife=halflife, times="C").mean()) - .iloc[[0, 3, 6, 9, 1, 4, 7, 2, 5, 8]] - .reset_index(drop=True) + .apply(lambda x: x.ewm(halflife=halflife, times="C").mean()) + .iloc[[0, 3, 6, 9, 1, 4, 7, 2, 5, 8]] + .reset_index(drop=True) ) tm.assert_frame_equal(result.reset_index(drop=True), expected) @@ -1003,7 +1003,7 @@ def test_times_array(self, times_frame): result = times_frame.groupby("A").ewm(halflife=halflife, times="C").mean() expected = ( times_frame.groupby("A") - .ewm(halflife=halflife, times=times_frame["C"].values) - .mean() + .ewm(halflife=halflife, times=times_frame["C"].values) + .mean() ) tm.assert_frame_equal(result, expected) From 0310b5358d8b9bcfa4ffa1bbd2d86e06d77aa018 Mon Sep 17 00:00:00 2001 From: benHeid Date: Fri, 23 Jul 2021 12:54:10 +0200 Subject: [PATCH 7/9] Fix linting errors. --- pandas/tests/window/test_groupby.py | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/pandas/tests/window/test_groupby.py b/pandas/tests/window/test_groupby.py index 47b3ce03c363b..5457f3ac780e3 100644 --- a/pandas/tests/window/test_groupby.py +++ b/pandas/tests/window/test_groupby.py @@ -696,22 +696,28 @@ def test_groupby_rolling_object_doesnt_affect_groupby_apply(self): assert not g.grouper.mutated @pytest.mark.parametrize( - ("window", "min_periods", "closed", "expected"), [ + ("window", "min_periods", "closed", "expected"), + [ (2, 0, "left", [None, 0.0, 1.0, 1.0, None, 0.0, 1.0, 1.0]), (2, 2, "left", [None, None, 1.0, 1.0, None, None, 1.0, 1.0]), (4, 4, "left", [None, None, None, None, None, None, None, None]), - (4, 4, "right", [None, None, None, 5.0, None, None, None, 5.0]) - ]) + (4, 4, "right", [None, None, None, 5.0, None, None, None, 5.0]), + ], + ) def test_groupby_rolling_var(self, window, min_periods, closed, expected): df = DataFrame([1, 2, 3, 4, 5, 6, 7, 8]) - result = df.groupby([1, 2, 1, 2, 1, 2, 1, 2]).rolling(window=window, - min_periods=min_periods, - closed=closed).var(0) - expected_result = DataFrame(np.array(expected, dtype="float64"), - index=MultiIndex(levels=[[1, 2], - [0, 1, 2, 3, 4, 5, 6, 7]], - codes=[[0, 0, 0, 0, 1, 1, 1, 1], - [0, 2, 4, 6, 1, 3, 5, 7]])) + result = ( + df.groupby([1, 2, 1, 2, 1, 2, 1, 2]) + .rolling(window=window, min_periods=min_periods, closed=closed) + .var(0) + ) + expected_result = DataFrame( + np.array(expected, dtype="float64"), + index=MultiIndex( + levels=[[1, 2], [0, 1, 2, 3, 4, 5, 6, 7]], + codes=[[0, 0, 0, 0, 1, 1, 1, 1], [0, 2, 4, 6, 1, 3, 5, 7]], + ), + ) tm.assert_frame_equal(result, expected_result) From 9797d204d18c1d9df81765a6ba0a66b7226d6942 Mon Sep 17 00:00:00 2001 From: benHeid Date: Fri, 23 Jul 2021 17:12:17 +0200 Subject: [PATCH 8/9] Fix linting error --- pandas/tests/window/test_groupby.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/pandas/tests/window/test_groupby.py b/pandas/tests/window/test_groupby.py index 5457f3ac780e3..03b43026c9a6c 100644 --- a/pandas/tests/window/test_groupby.py +++ b/pandas/tests/window/test_groupby.py @@ -720,8 +720,6 @@ def test_groupby_rolling_var(self, window, min_periods, closed, expected): ) tm.assert_frame_equal(result, expected_result) - - @pytest.mark.parametrize( "columns", [MultiIndex.from_tuples([("A", ""), ("B", "C")]), ["A", "B"]] ) From d39569f180998da284cd7b82f1de465eb31df119 Mon Sep 17 00:00:00 2001 From: benHeid Date: Sat, 24 Jul 2021 13:12:24 +0200 Subject: [PATCH 9/9] Add comment in the release notes --- doc/source/whatsnew/v1.4.0.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v1.4.0.rst b/doc/source/whatsnew/v1.4.0.rst index 92cf2bed9ca47..e74cc013ba201 100644 --- a/doc/source/whatsnew/v1.4.0.rst +++ b/doc/source/whatsnew/v1.4.0.rst @@ -244,7 +244,7 @@ Plotting Groupby/resample/rolling ^^^^^^^^^^^^^^^^^^^^^^^^ - Bug in :meth:`Series.rolling.apply`, :meth:`DataFrame.rolling.apply`, :meth:`Series.expanding.apply` and :meth:`DataFrame.expanding.apply` with ``engine="numba"`` where ``*args`` were being cached with the user passed function (:issue:`42287`) -- +- Bug in :meth:`DataFrame.groupby.rolling.var` would calculate the rolling variance only on the first group (:issue:`42442`) Reshaping ^^^^^^^^^