df.rolling(7, center=True).mean()
The rolling mean can be centered by setting the center argument to True.
Example plot
Answer from abrac on Stack OverflowTry the following (tested with pandas==0.23.3):
series.rolling('7D', min_periods=1, closed='left').sum().shift(-84, freq='h')
This will center your rolling sum in the 7-day window (by shifting -3.5 days), and will allow you to use a 'datetimelike' string for defining the window size. Note that shift() only takes an integer, thus defining with hours.
This will produce your desired output:
series.rolling('7D', min_periods=1, closed='left').sum().shift(-84, freq='h')['2014-01-01':].head(10)
2014-01-01 12:00:00 4.0
2014-01-02 12:00:00 5.0
2014-01-03 12:00:00 6.0
2014-01-04 12:00:00 7.0
2014-01-05 12:00:00 7.0
2014-01-06 12:00:00 7.0
2014-01-07 12:00:00 7.0
2014-01-08 12:00:00 7.0
2014-01-09 12:00:00 7.0
2014-01-10 12:00:00 7.0
Freq: D, dtype: float64
Note that the rolling sum is assigned to the center of the 7-day windows (using midnight to midnight timestamps), so the centered timestamp includes '12:00:00'.
Another option (as you show at the end of your question) is to resample the data to make sure it has even Datetime frequency, then use an integer for window size (window = 7) and center=True. However, you state that other parts of your code benefit from defining window with a 'datetimelike' string, so perhaps this option is not ideal.
From pandas version 1.3 this is * directly possible with pandas.
* Or will be (the work is merged, but 1.3 is not yet released as of today; I tested the lines below against the pandas main branch).
import pandas as pd
series = pd.Series(1, index = pd.date_range('2014-01-01', '2014-04-01', freq = 'D'))
series.rolling(7, min_periods=1, center=True).sum().head(10)
Output is as expected:
2014-01-01 4.0
2014-01-02 5.0
2014-01-03 6.0
2014-01-04 7.0
2014-01-05 7.0
2014-01-06 7.0
2014-01-07 7.0
2014-01-08 7.0
2014-01-09 7.0
2014-01-10 7.0
Freq: D, dtype: float64
I think you can use shift:
a = df.rolling(window=3).mean().shift(-2)
print (a)
A
0 3.666667
1 5.666667
2 11.333333
3 18.333333
4 NaN
5 NaN
Another solution is to simply reverse the DataFrame/Series before applying the right-aligned rolling window, and re-reverse it afterwards. Something like:
In [1]: df["A"][::-1].rolling(3).mean()[::-1]
Out[1]:
0 3.666667
1 5.666667
2 11.333333
3 18.333333
4 NaN
5 NaN
Name: A, dtype: float64
The benefit over shift is that it should work with variable sized windows in case of time-based windows.
