我想在具有日期索引的数据帧上应用偏移滚动窗口函数。 下面是一个示例:
rng = pd.date_range('2017-01-03', periods=20, freq='W')
df = pd.DataFrame(np.random.randn(20), rng, columns=['Val'])
df.index.name = 'Date'
r = df.rolling('15D')
这将生成一个数据帧df
如下所示:
Val
Date
2017-01-08 0.592210
2017-01-15 -1.243938
2017-01-22 -0.713988
2017-01-29 1.554777
...
但是我不知道如何在应用于Rolling
窗口的任何函数中查看与每个 Val 关联的日期。 例如,以下内容:
def f(data=None): # I really want to reference the Date associated with each Val in here!
print('f(%s) data=%s' % (str(type(data)), data))
return 1
r.apply(lambda x: f(x))
显示我只能看到每个呼叫的ndarray
:
f(<class 'numpy.ndarray'>) data=[0.59220959]
f(<class 'numpy.ndarray'>) data=[ 0.59220959 -1.24393841]
f(<class 'numpy.ndarray'>) data=[ 0.59220959 -1.24393841 -0.71398767]
f(<class 'numpy.ndarray'>) data=[-1.24393841 -0.71398767 1.55477737]
...
有没有办法在数据帧上调用时间偏移滚动窗口,以便聚合函数看到与窗口中每个值关联的索引?
例如,这样我就可以应用一个看到以下内容的函数:
f(<class 'DataFrame'>) data=[{2017-01-08, 0.59221}]
f(<class 'DataFrame'>) data=[{2017-01-08, 0.59221}, {2017-01-15, -1.243938}]
...
在最新版本中是可能的.apply(..., raw=False)
诀窍是定义一个可以访问整个数据帧的函数。然后,您在任何列上执行滚动,并在传入该函数apply()
调用。该函数将有权访问窗口数据,该数据是数据帧列的子集。从该子集中,您可以提取应查看的索引。(这假设您的指数正在严格增加。因此,通常的整数索引以及大多数时间序列都可以使用。然后,可以使用索引访问包含所有列的整个数据帧。
def dataframe_roll(df):
def my_fn(window_series):
# Note: you can do any kind of offset here
window_df = df[(df.index >= window_series.index[0]) & (df.index <= window_series.index[-1])]
return window_df["col1"] + window_df["col2"]
return my_fn
df["result"] = df["any_col"].rolling(24).apply(dataframe_roll(df), raw=False)
没有办法只用pd.rolling
来做到这一点。以下是受最近 SO 问题启发的解决方法:
s = pd.Series([df.loc[d - pd.offsets.DateOffset(days=15):d, 'Val'] for d in df.index])
这将构建一系列系列,其中每个子系列都包含您希望函数查看的日期和 Val。 即,使用您的示例函数,s.apply(f)
产生:
f(<class 'pandas.core.series.Series'>) data=Date
2017-01-08 -1.662699
Freq: W-SUN, Name: Val, dtype: float64
f(<class 'pandas.core.series.Series'>) data=Date
2017-01-08 -1.662699
2017-01-15 0.478471
Freq: W-SUN, Name: Val, dtype: float64
f(<class 'pandas.core.series.Series'>) data=Date
2017-01-08 -1.662699
2017-01-15 0.478471
2017-01-22 -0.552616
Freq: W-SUN, Name: Val, dtype: float64
f(<class 'pandas.core.series.Series'>) data=Date
2017-01-15 0.478471
2017-01-22 -0.552616
2017-01-29 -2.190669
...