diff --git a/doc/source/whatsnew/v0.20.2.txt b/doc/source/whatsnew/v0.20.2.txt index 13365401f1d1c..8182a1c111a0a 100644 --- a/doc/source/whatsnew/v0.20.2.txt +++ b/doc/source/whatsnew/v0.20.2.txt @@ -80,6 +80,7 @@ Groupby/Resample/Rolling ^^^^^^^^^^^^^^^^^^^^^^^^ - Bug creating datetime rolling window on an empty DataFrame (:issue:`15819`) +- Bug in ``rolling.cov()`` with offset window (:issue:`16058`) Sparse diff --git a/pandas/core/window.py b/pandas/core/window.py index cf1bad706ae1d..ba7e79944ab0e 100644 --- a/pandas/core/window.py +++ b/pandas/core/window.py @@ -81,6 +81,7 @@ def __init__(self, obj, window=None, min_periods=None, freq=None, self.freq = freq self.center = center self.win_type = win_type + self.win_freq = None self.axis = obj._get_axis_number(axis) if axis is not None else None self.validate() @@ -996,7 +997,12 @@ def cov(self, other=None, pairwise=None, ddof=1, **kwargs): # only default unset pairwise = True if pairwise is None else pairwise other = self._shallow_copy(other) - window = self._get_window(other) + + # GH 16058: offset window + if self.is_freq_type: + window = self.win_freq + else: + window = self._get_window(other) def _get_cov(X, Y): # GH #12373 : rolling functions error on float32 data @@ -1088,6 +1094,7 @@ def validate(self): "based windows") # this will raise ValueError on non-fixed freqs + self.win_freq = self.window self.window = freq.nanos self.win_type = 'freq' diff --git a/pandas/tests/test_window.py b/pandas/tests/test_window.py index 6a640d62108b3..cbb3c345a9353 100644 --- a/pandas/tests/test_window.py +++ b/pandas/tests/test_window.py @@ -3833,3 +3833,26 @@ def test_non_monotonic(self): df2 = df.sort_values('B') result = df2.groupby('A').rolling('4s', on='B').C.mean() tm.assert_series_equal(result, expected) + + def test_rolling_cov_offset(self): + # GH16058 + + idx = pd.date_range('2017-01-01', periods=24, freq='1h') + ss = pd.Series(np.arange(len(idx)), index=idx) + + result = ss.rolling('2h').cov() + expected = pd.Series([np.nan] + [0.5 for _ in range(len(idx) - 1)], + index=idx) + tm.assert_series_equal(result, expected) + + expected2 = ss.rolling(2, min_periods=1).cov() + tm.assert_series_equal(result, expected2) + + result = ss.rolling('3h').cov() + expected = pd.Series([np.nan, 0.5] + + [1.0 for _ in range(len(idx) - 2)], + index=idx) + tm.assert_series_equal(result, expected) + + expected2 = ss.rolling(3, min_periods=1).cov() + tm.assert_series_equal(result, expected2)