Define your own roll
We can create a function that takes a window size argument w and any other key arguments. We use this to create a new DataFrame in which we will call groupby when passing the keyword arguments through kwargs .
Note: I did not need to use
stride_tricks.as_strided , but it is concise and, in my opinion, appropriate.
from numpy.lib.stride_tricks import as_strided as stride import pandas as pd def roll(df, w, **kwargs): v = df.values d0, d1 = v.shape s0, s1 = v.strides a = stride(v, (d0 - (w - 1), w, d1), (s0, s0, s1)) rolled_df = pd.concat({ row: pd.DataFrame(values, columns=df.columns) for row, values in zip(df.index, a) }) return rolled_df.groupby(level=0, **kwargs) roll(df, 2).mean() Open High Low Close 0 133.0350 133.2975 132.8250 132.930 1 132.9325 133.1200 132.6750 132.745 2 132.7425 132.8875 132.6075 132.710 3 132.7075 132.7875 132.6000 132.720
We can also use the pandas.DataFrame.pipe method for the same effect:
df.pipe(roll, w=2).mean()
OLD RESPONSE
Panel deprecated. See above for an updated answer.
see fooobar.com/questions/456684 / ...
define our own roll
def roll(df, w, **kwargs): roll_array = np.dstack([df.values[i:i+w, :] for i in range(len(df.index) - w + 1)]).T panel = pd.Panel(roll_array, items=df.index[w-1:], major_axis=df.columns, minor_axis=pd.Index(range(w), name='roll')) return panel.to_frame().unstack().T.groupby(level=0, **kwargs)
You must be able to:
roll(df, 2).apply(your_function)
Using mean
roll(df, 2).mean() major Open High Low Close 1 133.0350 133.2975 132.8250 132.930 2 132.9325 133.1200 132.6750 132.745 3 132.7425 132.8875 132.6075 132.710 4 132.7075 132.7875 132.6000 132.720
f = lambda df: df.sum(1) roll(df, 2, group_keys=False).apply(f) roll 1 0 532.345 1 531.830 2 0 531.830 1 531.115 3 0 531.115 1 530.780 4 0 530.780 1 530.850 dtype: float64