0

我想在具有日期索引的 DataFrame 上应用偏移滚动窗口函数。这是一个例子:

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')

这会产生一个 DataFrame 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]
...

有没有办法以聚合函数看到与窗口中每个值关联的索引的方式在 DataFrame 上调用时间偏移滚动窗口?

例如,这样我就可以应用一个看起来像这样的函数:

f(<class 'DataFrame'>) data=[{2017-01-08, 0.59221}]
f(<class 'DataFrame'>) data=[{2017-01-08, 0.59221}, {2017-01-15, -1.243938}]
...
4

2 回答 2

4

这在最近的版本中是可能的.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)
于 2019-07-29T21:27:38.193 回答
2

我不认为有一种方法可以做到这一点pd.rolling这是受最近 SO question启发的解决方法:

s = pd.Series([df.loc[d - pd.offsets.DateOffset(days=15):d, 'Val'] for d in df.index])

这将构建一系列系列,其中每个子系列包含您希望函数看到的日期和值。即,使用您的示例函数,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
...
于 2018-03-05T22:29:10.550 回答