From 5813517e4d299fd7463f040b5db43f2c5bd866e5 Mon Sep 17 00:00:00 2001 From: Matt Roeschke Date: Wed, 18 Nov 2020 10:32:18 -0800 Subject: [PATCH 1/7] Use more parameterization --- .../test_moments_consistency_rolling.py | 132 +++++++++--------- 1 file changed, 66 insertions(+), 66 deletions(-) diff --git a/pandas/tests/window/moments/test_moments_consistency_rolling.py b/pandas/tests/window/moments/test_moments_consistency_rolling.py index b7b05c1a6e30d..12a2de30d3740 100644 --- a/pandas/tests/window/moments/test_moments_consistency_rolling.py +++ b/pandas/tests/window/moments/test_moments_consistency_rolling.py @@ -174,14 +174,9 @@ def test_corr_sanity(): res = df[0].rolling(5, center=True).corr(df[1]) assert all(np.abs(np.nan_to_num(x)) <= 1 for x in res) - # and some fuzzing - for _ in range(10): - df = DataFrame(np.random.rand(30, 2)) - res = df[0].rolling(5, center=True).corr(df[1]) - try: - assert all(np.abs(np.nan_to_num(x)) <= 1 for x in res) - except AssertionError: - print(res) + df = DataFrame(np.random.rand(30, 2)) + res = df[0].rolling(5, center=True).corr(df[1]) + assert all(np.abs(np.nan_to_num(x)) <= 1 for x in res) def test_rolling_cov_diff_length(): @@ -227,10 +222,12 @@ def test_rolling_corr_diff_length(): lambda x: x.rolling(window=10, min_periods=5).median(), lambda x: x.rolling(window=10, min_periods=5).apply(sum, raw=False), lambda x: x.rolling(window=10, min_periods=5).apply(sum, raw=True), - lambda x: x.rolling(win_type="boxcar", window=10, min_periods=5).mean(), + pytest.param( + lambda x: x.rolling(win_type="boxcar", window=10, min_periods=5).mean(), + marks=td.skip_if_no_scipy, + ), ], ) -@td.skip_if_no_scipy def test_rolling_functions_window_non_shrinkage(f): # GH 7764 s = Series(range(4)) @@ -245,7 +242,14 @@ def test_rolling_functions_window_non_shrinkage(f): tm.assert_frame_equal(df_result, df_expected) -def test_rolling_functions_window_non_shrinkage_binary(): +@pytest.mark.parametrize( + "f", + [ + lambda x: (x.rolling(window=10, min_periods=5).cov(x, pairwise=True)), + lambda x: (x.rolling(window=10, min_periods=5).corr(x, pairwise=True)), + ], +) +def test_rolling_functions_window_non_shrinkage_binary(f): # corr/cov return a MI DataFrame df = DataFrame( @@ -258,13 +262,8 @@ def test_rolling_functions_window_non_shrinkage_binary(): index=pd.MultiIndex.from_product([df.index, df.columns], names=["bar", "foo"]), dtype="float64", ) - functions = [ - lambda x: (x.rolling(window=10, min_periods=5).cov(x, pairwise=True)), - lambda x: (x.rolling(window=10, min_periods=5).corr(x, pairwise=True)), - ] - for f in functions: - df_result = f(df) - tm.assert_frame_equal(df_result, df_expected) + df_result = f(df) + tm.assert_frame_equal(df_result, df_expected) def test_rolling_skew_edge_cases(): @@ -427,34 +426,26 @@ def test_rolling_median_memory_error(): Series(np.random.randn(n)).rolling(window=2, center=False).median() -def test_rolling_min_max_numeric_types(): - +@pytest.mark.parametrize( + "data_type", + [np.dtype(f"f{width}") for width in [4, 8]] + + [np.dtype(f"{sign}{width}") for width in [1, 2, 4, 8] for sign in "ui"], +) +def test_rolling_min_max_numeric_types(data_type): # GH12373 - types_test = [np.dtype(f"f{width}") for width in [4, 8]] - types_test.extend( - [np.dtype(f"{sign}{width}") for width in [1, 2, 4, 8] for sign in "ui"] - ) - for data_type in types_test: - # Just testing that these don't throw exceptions and that - # the return type is float64. Other tests will cover quantitative - # correctness - result = DataFrame(np.arange(20, dtype=data_type)).rolling(window=5).max() - assert result.dtypes[0] == np.dtype("f8") - result = DataFrame(np.arange(20, dtype=data_type)).rolling(window=5).min() - assert result.dtypes[0] == np.dtype("f8") + # Just testing that these don't throw exceptions and that + # the return type is float64. Other tests will cover quantitative + # correctness + result = DataFrame(np.arange(20, dtype=data_type)).rolling(window=5).max() + assert result.dtypes[0] == np.dtype("f8") + result = DataFrame(np.arange(20, dtype=data_type)).rolling(window=5).min() + assert result.dtypes[0] == np.dtype("f8") -def test_moment_functions_zero_length(): - # GH 8056 - s = Series(dtype=np.float64) - s_expected = s - df1 = DataFrame() - df1_expected = df1 - df2 = DataFrame(columns=["a"]) - df2["a"] = df2["a"].astype("float64") - df2_expected = df2 - functions = [ +@pytest.mark.parametrize( + "f", + [ lambda x: x.rolling(window=10, min_periods=0).count(), lambda x: x.rolling(window=10, min_periods=5).cov(x, pairwise=False), lambda x: x.rolling(window=10, min_periods=5).corr(x, pairwise=False), @@ -470,25 +461,40 @@ def test_moment_functions_zero_length(): lambda x: x.rolling(window=10, min_periods=5).median(), lambda x: x.rolling(window=10, min_periods=5).apply(sum, raw=False), lambda x: x.rolling(window=10, min_periods=5).apply(sum, raw=True), - lambda x: x.rolling(win_type="boxcar", window=10, min_periods=5).mean(), - ] - for f in functions: - try: - s_result = f(s) - tm.assert_series_equal(s_result, s_expected) + pytest.param( + lambda x: x.rolling(win_type="boxcar", window=10, min_periods=5).mean(), + marks=td.skip_if_no_scipy, + ), + ], +) +def test_moment_functions_zero_length(f): + # GH 8056 + s = Series(dtype=np.float64) + s_expected = s + df1 = DataFrame() + df1_expected = df1 + df2 = DataFrame(columns=["a"]) + df2["a"] = df2["a"].astype("float64") + df2_expected = df2 - df1_result = f(df1) - tm.assert_frame_equal(df1_result, df1_expected) + s_result = f(s) + tm.assert_series_equal(s_result, s_expected) - df2_result = f(df2) - tm.assert_frame_equal(df2_result, df2_expected) - except (ImportError): + df1_result = f(df1) + tm.assert_frame_equal(df1_result, df1_expected) - # scipy needed for rolling_window - continue + df2_result = f(df2) + tm.assert_frame_equal(df2_result, df2_expected) -def test_moment_functions_zero_length_pairwise(): +@pytest.mark.parametrize( + "f", + [ + lambda x: (x.rolling(window=10, min_periods=5).cov(x, pairwise=True)), + lambda x: (x.rolling(window=10, min_periods=5).corr(x, pairwise=True)), + ], +) +def test_moment_functions_zero_length_pairwise(f): df1 = DataFrame() df2 = DataFrame(columns=Index(["a"], name="foo"), index=Index([], name="bar")) @@ -505,17 +511,11 @@ def test_moment_functions_zero_length_pairwise(): dtype="float64", ) - functions = [ - lambda x: (x.rolling(window=10, min_periods=5).cov(x, pairwise=True)), - lambda x: (x.rolling(window=10, min_periods=5).corr(x, pairwise=True)), - ] - - for f in functions: - df1_result = f(df1) - tm.assert_frame_equal(df1_result, df1_expected) + df1_result = f(df1) + tm.assert_frame_equal(df1_result, df1_expected) - df2_result = f(df2) - tm.assert_frame_equal(df2_result, df2_expected) + df2_result = f(df2) + tm.assert_frame_equal(df2_result, df2_expected) @pytest.mark.slow From 293fef5c8aea4bd85b472035b2de7eb7929281b8 Mon Sep 17 00:00:00 2001 From: Matt Roeschke Date: Wed, 18 Nov 2020 11:02:19 -0800 Subject: [PATCH 2/7] Refactor out consistency tests --- .../test_moments_consistency_rolling.py | 121 +++++++++--------- 1 file changed, 62 insertions(+), 59 deletions(-) diff --git a/pandas/tests/window/moments/test_moments_consistency_rolling.py b/pandas/tests/window/moments/test_moments_consistency_rolling.py index 12a2de30d3740..e3c2b09819fbf 100644 --- a/pandas/tests/window/moments/test_moments_consistency_rolling.py +++ b/pandas/tests/window/moments/test_moments_consistency_rolling.py @@ -628,71 +628,74 @@ def test_rolling_consistency_series(consistency_data, window, min_periods, cente ) -@pytest.mark.slow @pytest.mark.parametrize( "window,min_periods,center", list(_rolling_consistency_cases()) ) -def test_rolling_consistency(consistency_data, window, min_periods, center): +def test_rolling_consistency_mean(consistency_data, window, min_periods, center): x, is_constant, no_nans = consistency_data - # suppress warnings about empty slices, as we are deliberately testing - # with empty/0-length Series/DataFrames - with warnings.catch_warnings(): - warnings.filterwarnings( - "ignore", message=".*(empty slice|0 for slice).*", category=RuntimeWarning - ) - # test consistency between different rolling_* moments - moments_consistency_mock_mean( - x=x, - mean=lambda x: ( - x.rolling(window=window, min_periods=min_periods, center=center).mean() - ), - mock_mean=lambda x: ( - x.rolling(window=window, min_periods=min_periods, center=center) - .sum() - .divide( - x.rolling( - window=window, min_periods=min_periods, center=center - ).count() - ) - ), + result = x.rolling(window=window, min_periods=min_periods, center=center).mean() + expected = ( + x.rolling(window=window, min_periods=min_periods, center=center) + .sum() + .divide( + x.rolling(window=window, min_periods=min_periods, center=center).count() ) + ) + tm.assert_equal(result, expected.astype("float64")) - moments_consistency_is_constant( - x=x, - is_constant=is_constant, - min_periods=min_periods, - count=lambda x: ( - x.rolling(window=window, min_periods=min_periods, center=center).count() - ), - mean=lambda x: ( - x.rolling(window=window, min_periods=min_periods, center=center).mean() - ), - corr=lambda x, y: ( - x.rolling(window=window, min_periods=min_periods, center=center).corr(y) - ), - ) - moments_consistency_var_debiasing_factors( - x=x, - var_unbiased=lambda x: ( - x.rolling(window=window, min_periods=min_periods, center=center).var() - ), - var_biased=lambda x: ( - x.rolling(window=window, min_periods=min_periods, center=center).var( - ddof=0 - ) - ), - var_debiasing_factors=lambda x: ( - x.rolling(window=window, min_periods=min_periods, center=center) - .count() - .divide( - ( - x.rolling( - window=window, min_periods=min_periods, center=center - ).count() - - 1.0 - ).replace(0.0, np.nan) - ) - ), +@pytest.mark.parametrize( + "window,min_periods,center", list(_rolling_consistency_cases()) +) +def test_rolling_consistency_constant(consistency_data, window, min_periods, center): + x, is_constant, no_nans = consistency_data + + if is_constant: + count_x = x.rolling( + window=window, min_periods=min_periods, center=center + ).count() + mean_x = x.rolling(window=window, min_periods=min_periods, center=center).mean() + # check that correlation of a series with itself is either 1 or NaN + corr_x_x = x.rolling( + window=window, min_periods=min_periods, center=center + ).corr(x) + + exp = x.max() if isinstance(x, Series) else x.max().max() + + # check mean of constant series + expected = x * np.nan + expected[count_x >= max(min_periods, 1)] = exp + tm.assert_equal(mean_x, expected) + + # check correlation of constant series with itself is NaN + expected[:] = np.nan + tm.assert_equal(corr_x_x, expected) + + +@pytest.mark.parametrize( + "window,min_periods,center", list(_rolling_consistency_cases()) +) +def test_rolling_consistency_var_debiasing_factors( + consistency_data, window, min_periods, center +): + x, is_constant, no_nans = consistency_data + + # check variance debiasing factors + var_unbiased_x = x.rolling( + window=window, min_periods=min_periods, center=center + ).var() + var_biased_x = x.rolling(window=window, min_periods=min_periods, center=center).var( + ddof=0 + ) + var_debiasing_factors_x = ( + x.rolling(window=window, min_periods=min_periods, center=center) + .count() + .divide( + ( + x.rolling(window=window, min_periods=min_periods, center=center).count() + - 1.0 + ).replace(0.0, np.nan) ) + ) + tm.assert_equal(var_unbiased_x, var_biased_x * var_debiasing_factors_x) From 625d328a69db628ef758ba8909899c6749c80d22 Mon Sep 17 00:00:00 2001 From: Matt Roeschke Date: Wed, 18 Nov 2020 12:26:19 -0800 Subject: [PATCH 3/7] Refactor series tests --- .../test_moments_consistency_rolling.py | 121 +++++++++++++----- 1 file changed, 91 insertions(+), 30 deletions(-) diff --git a/pandas/tests/window/moments/test_moments_consistency_rolling.py b/pandas/tests/window/moments/test_moments_consistency_rolling.py index e3c2b09819fbf..66c89013b4ed7 100644 --- a/pandas/tests/window/moments/test_moments_consistency_rolling.py +++ b/pandas/tests/window/moments/test_moments_consistency_rolling.py @@ -591,41 +591,102 @@ def test_rolling_consistency_cov(consistency_data, window, min_periods, center): ) -@pytest.mark.slow @pytest.mark.parametrize( "window,min_periods,center", list(_rolling_consistency_cases()) ) -def test_rolling_consistency_series(consistency_data, window, min_periods, center): +@pytest.mark.parametrize("ddof", [0, 1]) +def test_rolling_consistency_series_std(consistency_data, window, min_periods, center, ddof): x, is_constant, no_nans = consistency_data - moments_consistency_series_data( - x=x, - mean=lambda x: ( - x.rolling(window=window, min_periods=min_periods, center=center).mean() - ), - corr=lambda x, y: ( - x.rolling(window=window, min_periods=min_periods, center=center).corr(y) - ), - var_unbiased=lambda x: ( - x.rolling(window=window, min_periods=min_periods, center=center).var() - ), - std_unbiased=lambda x: ( - x.rolling(window=window, min_periods=min_periods, center=center).std() - ), - cov_unbiased=lambda x, y: ( - x.rolling(window=window, min_periods=min_periods, center=center).cov(y) - ), - var_biased=lambda x: ( - x.rolling(window=window, min_periods=min_periods, center=center).var(ddof=0) - ), - std_biased=lambda x: ( - x.rolling(window=window, min_periods=min_periods, center=center).std(ddof=0) - ), - cov_biased=lambda x, y: ( - x.rolling(window=window, min_periods=min_periods, center=center).cov( - y, ddof=0 - ) - ), + + var_x = x.rolling(window=window, min_periods=min_periods, center=center).var( + ddof=ddof + ) + std_x = x.rolling(window=window, min_periods=min_periods, center=center).std( + ddof=ddof ) + assert not (var_x < 0).any().any() + assert not (std_x < 0).any().any() + + # check that var(x) == std(x)^2 + tm.assert_equal(var_x, std_x * std_x) + + +@pytest.mark.parametrize( + "window,min_periods,center", list(_rolling_consistency_cases()) +) +@pytest.mark.parametrize("ddof", [0, 1]) +def test_rolling_consistency_series_cov(consistency_data, window, min_periods, center, ddof): + x, is_constant, no_nans = consistency_data + var_x = x.rolling(window=window, min_periods=min_periods, center=center).var( + ddof=ddof + ) + assert not (var_x < 0).any().any() + + cov_x_x = x.rolling(window=window, min_periods=min_periods, center=center).cov( + x, ddof=ddof + ) + assert not (cov_x_x < 0).any().any() + + # check that var(x) == cov(x, x) + tm.assert_equal(var_x, cov_x_x) + + +@pytest.mark.parametrize( + "window,min_periods,center", list(_rolling_consistency_cases()) +) +@pytest.mark.parametrize("ddof", [0, 1]) +def test_rolling_consistency_series_cov_corr( + consistency_data, window, min_periods, center, ddof +): + x, is_constant, no_nans = consistency_data + + if isinstance(x, Series): + var_x_plus_y = ( + (x + x) + .rolling(window=window, min_periods=min_periods, center=center) + .var(ddof=ddof) + ) + var_x = x.rolling(window=window, min_periods=min_periods, center=center).var( + ddof=ddof + ) + var_y = x.rolling(window=window, min_periods=min_periods, center=center).var( + ddof=ddof + ) + cov_x_y = x.rolling(window=window, min_periods=min_periods, center=center).cov( + x, ddof=ddof + ) + # check that cov(x, y) == (var(x+y) - var(x) - + # var(y)) / 2 + tm.assert_equal(cov_x_y, 0.5 * (var_x_plus_y - var_x - var_y)) + + # check that corr(x, y) == cov(x, y) / (std(x) * + # std(y)) + corr_x_y = x.rolling( + window=window, min_periods=min_periods, center=center + ).corr(x) + std_x = x.rolling(window=window, min_periods=min_periods, center=center).std( + ddof=ddof + ) + std_y = x.rolling(window=window, min_periods=min_periods, center=center).std( + ddof=ddof + ) + tm.assert_equal(corr_x_y, cov_x_y / (std_x * std_y)) + + if ddof == 0: + # check that biased cov(x, y) == mean(x*y) - + # mean(x)*mean(y) + mean_x = x.rolling( + window=window, min_periods=min_periods, center=center + ).mean() + mean_y = x.rolling( + window=window, min_periods=min_periods, center=center + ).mean() + mean_x_times_y = ( + (x * x) + .rolling(window=window, min_periods=min_periods, center=center) + .mean() + ) + tm.assert_equal(cov_x_y, mean_x_times_y - (mean_x * mean_y)) @pytest.mark.parametrize( From 294932158e5386dd4bc99a328350f8352cc31a86 Mon Sep 17 00:00:00 2001 From: Matt Roeschke Date: Wed, 18 Nov 2020 13:11:31 -0800 Subject: [PATCH 4/7] Refactor corr std and var tests --- .../test_moments_consistency_rolling.py | 96 +++++++------------ 1 file changed, 36 insertions(+), 60 deletions(-) diff --git a/pandas/tests/window/moments/test_moments_consistency_rolling.py b/pandas/tests/window/moments/test_moments_consistency_rolling.py index 66c89013b4ed7..6f7b7a6d47280 100644 --- a/pandas/tests/window/moments/test_moments_consistency_rolling.py +++ b/pandas/tests/window/moments/test_moments_consistency_rolling.py @@ -518,84 +518,60 @@ def test_moment_functions_zero_length_pairwise(f): tm.assert_frame_equal(df2_result, df2_expected) -@pytest.mark.slow @pytest.mark.parametrize( "window,min_periods,center", list(_rolling_consistency_cases()) ) -def test_rolling_consistency_var(consistency_data, window, min_periods, center): +@pytest.mark.parametrize("ddof", [0, 1]) +def test_moments_consistency_var(consistency_data, window, min_periods, center, ddof): x, is_constant, no_nans = consistency_data - moments_consistency_var_data( - x=x, - is_constant=is_constant, - min_periods=min_periods, - count=lambda x: ( - x.rolling(window=window, min_periods=min_periods, center=center).count() - ), - mean=lambda x: ( - x.rolling(window=window, min_periods=min_periods, center=center).mean() - ), - var_unbiased=lambda x: ( - x.rolling(window=window, min_periods=min_periods, center=center).var() - ), - var_biased=lambda x: ( - x.rolling(window=window, min_periods=min_periods, center=center).var(ddof=0) - ), + + mean_x = x.rolling(window=window, min_periods=min_periods, center=center).mean() + var_x = x.rolling(window=window, min_periods=min_periods, center=center).var( + ddof=ddof ) + assert not (var_x < 0).any().any() + + if ddof == 0: + # check that biased var(x) == mean(x^2) - mean(x)^2 + mean_x2 = ( + (x * x) + .rolling(window=window, min_periods=min_periods, center=center) + .mean() + ) + tm.assert_equal(var_x, mean_x2 - (mean_x * mean_x)) -@pytest.mark.slow @pytest.mark.parametrize( "window,min_periods,center", list(_rolling_consistency_cases()) ) -def test_rolling_consistency_std(consistency_data, window, min_periods, center): +@pytest.mark.parametrize("ddof", [0, 1]) +def test_moments_consistency_var_constant( + consistency_data, window, min_periods, center, ddof +): x, is_constant, no_nans = consistency_data - moments_consistency_std_data( - x=x, - var_unbiased=lambda x: ( - x.rolling(window=window, min_periods=min_periods, center=center).var() - ), - std_unbiased=lambda x: ( - x.rolling(window=window, min_periods=min_periods, center=center).std() - ), - var_biased=lambda x: ( - x.rolling(window=window, min_periods=min_periods, center=center).var(ddof=0) - ), - std_biased=lambda x: ( - x.rolling(window=window, min_periods=min_periods, center=center).std(ddof=0) - ), - ) + if is_constant: + count_x = x.rolling( + window=window, min_periods=min_periods, center=center + ).count() + var_x = x.rolling(window=window, min_periods=min_periods, center=center).var( + ddof=ddof + ) -@pytest.mark.slow -@pytest.mark.parametrize( - "window,min_periods,center", list(_rolling_consistency_cases()) -) -def test_rolling_consistency_cov(consistency_data, window, min_periods, center): - x, is_constant, no_nans = consistency_data - moments_consistency_cov_data( - x=x, - var_unbiased=lambda x: ( - x.rolling(window=window, min_periods=min_periods, center=center).var() - ), - cov_unbiased=lambda x, y: ( - x.rolling(window=window, min_periods=min_periods, center=center).cov(y) - ), - var_biased=lambda x: ( - x.rolling(window=window, min_periods=min_periods, center=center).var(ddof=0) - ), - cov_biased=lambda x, y: ( - x.rolling(window=window, min_periods=min_periods, center=center).cov( - y, ddof=0 - ) - ), - ) + # check that variance of constant series is identically 0 + assert not (var_x > 0).any().any() + expected = x * np.nan + expected[count_x >= max(min_periods, 1)] = 0.0 + if ddof == 1: + expected[count_x < 2] = np.nan + tm.assert_equal(var_x, expected) @pytest.mark.parametrize( "window,min_periods,center", list(_rolling_consistency_cases()) ) @pytest.mark.parametrize("ddof", [0, 1]) -def test_rolling_consistency_series_std(consistency_data, window, min_periods, center, ddof): +def test_rolling_consistency_std(consistency_data, window, min_periods, center, ddof): x, is_constant, no_nans = consistency_data var_x = x.rolling(window=window, min_periods=min_periods, center=center).var( @@ -615,7 +591,7 @@ def test_rolling_consistency_series_std(consistency_data, window, min_periods, c "window,min_periods,center", list(_rolling_consistency_cases()) ) @pytest.mark.parametrize("ddof", [0, 1]) -def test_rolling_consistency_series_cov(consistency_data, window, min_periods, center, ddof): +def test_rolling_consistency_cov(consistency_data, window, min_periods, center, ddof): x, is_constant, no_nans = consistency_data var_x = x.rolling(window=window, min_periods=min_periods, center=center).var( ddof=ddof From 0e28dd0a2717f736c0acb105c41de94f0841ab57 Mon Sep 17 00:00:00 2001 From: Matt Roeschke Date: Wed, 18 Nov 2020 13:21:27 -0800 Subject: [PATCH 5/7] Simplify apply tests --- .../test_moments_consistency_rolling.py | 84 ++++++++----------- 1 file changed, 33 insertions(+), 51 deletions(-) diff --git a/pandas/tests/window/moments/test_moments_consistency_rolling.py b/pandas/tests/window/moments/test_moments_consistency_rolling.py index 6f7b7a6d47280..f42e929e3703f 100644 --- a/pandas/tests/window/moments/test_moments_consistency_rolling.py +++ b/pandas/tests/window/moments/test_moments_consistency_rolling.py @@ -10,15 +10,6 @@ from pandas import DataFrame, DatetimeIndex, Index, Series import pandas._testing as tm from pandas.core.window.common import flex_binary_moment -from pandas.tests.window.common import ( - moments_consistency_cov_data, - moments_consistency_is_constant, - moments_consistency_mock_mean, - moments_consistency_series_data, - moments_consistency_std_data, - moments_consistency_var_data, - moments_consistency_var_debiasing_factors, -) def _rolling_consistency_cases(): @@ -87,56 +78,47 @@ def test_flex_binary_frame(method, frame): tm.assert_frame_equal(res3, exp) -@pytest.mark.slow @pytest.mark.parametrize( "window,min_periods,center", list(_rolling_consistency_cases()) ) -def test_rolling_apply_consistency( - consistency_data, base_functions, no_nan_functions, window, min_periods, center +@pytest.mark.parametrize("f", [lambda v: Series(v).sum(), np.nansum]) +def test_rolling_apply_consistency_sum_nans( + consistency_data, window, min_periods, center, f ): x, is_constant, no_nans = consistency_data - with warnings.catch_warnings(): - warnings.filterwarnings( - "ignore", message=".*(empty slice|0 for slice).*", category=RuntimeWarning - ) - # test consistency between rolling_xyz() and either (a) - # rolling_apply of Series.xyz(), or (b) rolling_apply of - # np.nanxyz() - functions = base_functions - - # GH 8269 - if no_nans: - functions = no_nan_functions + base_functions - for (f, require_min_periods, name) in functions: - rolling_f = getattr( - x.rolling(window=window, center=center, min_periods=min_periods), name - ) + if f is np.nansum and min_periods == 0: + pass + else: + rolling_f_result = x.rolling( + window=window, min_periods=min_periods, center=center + ).sum() + rolling_apply_f_result = x.rolling( + window=window, min_periods=min_periods, center=center + ).apply(func=f, raw=True) + tm.assert_equal(rolling_f_result, rolling_apply_f_result) - if ( - require_min_periods - and (min_periods is not None) - and (min_periods < require_min_periods) - ): - continue - if name == "count": - rolling_f_result = rolling_f() - rolling_apply_f_result = x.rolling( - window=window, min_periods=min_periods, center=center - ).apply(func=f, raw=True) - else: - if name in ["cov", "corr"]: - rolling_f_result = rolling_f(pairwise=False) - else: - rolling_f_result = rolling_f() - rolling_apply_f_result = x.rolling( - window=window, min_periods=min_periods, center=center - ).apply(func=f, raw=True) - - # GH 9422 - if name in ["sum", "prod"]: - tm.assert_equal(rolling_f_result, rolling_apply_f_result) +@pytest.mark.parametrize( + "window,min_periods,center", list(_rolling_consistency_cases()) +) +@pytest.mark.parametrize("f", [lambda v: Series(v).sum(), np.nansum, np.sum]) +def test_rolling_apply_consistency_sum_no_nans( + consistency_data, window, min_periods, center, f +): + x, is_constant, no_nans = consistency_data + + if no_nans: + if f is np.nansum and min_periods == 0: + pass + else: + rolling_f_result = x.rolling( + window=window, min_periods=min_periods, center=center + ).sum() + rolling_apply_f_result = x.rolling( + window=window, min_periods=min_periods, center=center + ).apply(func=f, raw=True) + tm.assert_equal(rolling_f_result, rolling_apply_f_result) @pytest.mark.parametrize("window", range(7)) From a0ad8e78db2487008337955f8affb8cde2329ec7 Mon Sep 17 00:00:00 2001 From: Matt Roeschke Date: Wed, 18 Nov 2020 13:22:34 -0800 Subject: [PATCH 6/7] Remove unused import --- pandas/tests/window/moments/test_moments_consistency_rolling.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pandas/tests/window/moments/test_moments_consistency_rolling.py b/pandas/tests/window/moments/test_moments_consistency_rolling.py index f42e929e3703f..ceabf71747cb8 100644 --- a/pandas/tests/window/moments/test_moments_consistency_rolling.py +++ b/pandas/tests/window/moments/test_moments_consistency_rolling.py @@ -1,5 +1,4 @@ from datetime import datetime -import warnings import numpy as np import pytest From a8ee04b56d6a306396e61d6ea436e90c512b6de2 Mon Sep 17 00:00:00 2001 From: Matt Roeschke Date: Wed, 18 Nov 2020 13:30:36 -0800 Subject: [PATCH 7/7] Remove unused fixtures after refactor --- pandas/tests/window/moments/conftest.py | 58 ------------------------- 1 file changed, 58 deletions(-) diff --git a/pandas/tests/window/moments/conftest.py b/pandas/tests/window/moments/conftest.py index 2fab7f5c91c09..ce4d04a9bcc1e 100644 --- a/pandas/tests/window/moments/conftest.py +++ b/pandas/tests/window/moments/conftest.py @@ -17,61 +17,3 @@ def binary_ew_data(): @pytest.fixture(params=[0, 1, 2]) def min_periods(request): return request.param - - -base_functions_list = [ - (lambda v: Series(v).count(), None, "count"), - (lambda v: Series(v).max(), None, "max"), - (lambda v: Series(v).min(), None, "min"), - (lambda v: Series(v).sum(), None, "sum"), - (lambda v: Series(v).mean(), None, "mean"), - (lambda v: Series(v).std(), 1, "std"), - (lambda v: Series(v).cov(Series(v)), None, "cov"), - (lambda v: Series(v).corr(Series(v)), None, "corr"), - (lambda v: Series(v).var(), 1, "var"), - # restore once GH 8086 is fixed - # lambda v: Series(v).skew(), 3, 'skew'), - # (lambda v: Series(v).kurt(), 4, 'kurt'), - # restore once GH 8084 is fixed - # lambda v: Series(v).quantile(0.3), None, 'quantile'), - (lambda v: Series(v).median(), None, "median"), - (np.nanmax, 1, "max"), - (np.nanmin, 1, "min"), - (np.nansum, 1, "sum"), - (np.nanmean, 1, "mean"), - (lambda v: np.nanstd(v, ddof=1), 1, "std"), - (lambda v: np.nanvar(v, ddof=1), 1, "var"), - (np.nanmedian, 1, "median"), -] - -no_nan_functions_list = [ - (np.max, None, "max"), - (np.min, None, "min"), - (np.sum, None, "sum"), - (np.mean, None, "mean"), - (lambda v: np.std(v, ddof=1), 1, "std"), - (lambda v: np.var(v, ddof=1), 1, "var"), - (np.median, None, "median"), -] - - -@pytest.fixture(scope="session") -def base_functions(): - """Fixture for base functions. - - Returns - ------- - List of tuples: (applied function, require_min_periods, name of applied function) - """ - return base_functions_list - - -@pytest.fixture(scope="session") -def no_nan_functions(): - """Fixture for no nan functions. - - Returns - ------- - List of tuples: (applied function, require_min_periods, name of applied function) - """ - return no_nan_functions_list