熊猫数据帧自定义滚动函数,可查看索引



我想在具有日期索引的数据帧上应用偏移滚动窗口函数。 下面是一个示例:

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
...

最新更新