在Pandas数据框中,是否有一种方法可以计算前瞻滚动值,以适应不同数量的行?

3
我询问的原因如下:
我有一组15分钟OHLC金融数据的时间序列。 我想计算的是:对于任何数据点,未来(因此是前瞻性的)特定时间段内的最高和最低价格是什么。 与该时间框架相关的确切行数无论是在数量上还是偏移位置上都不固定。
以下是一个示例来说明我的意思。
假设我拥有23.45 4月28日星期二的开盘价、最高价、最低价和收盘价。 我想知道以下时间段的最大值和最小值:
1.提前一天,因此需要将所有4月29日星期三的数据进行分组 2.提前一小时,因此将是接下来的4个行 3.提前一周,因此将从5月4日开始的所有672行(4行x24小时x7天),这将是下周的星期一。
正如您所看到的,该功能将“需要知道”其当前时间位置(在一天、一周或一个月中)如何确定我感兴趣的窗口(具有滑动变量的前瞻性和偏移量)。
是否有一种方法可以避免使用for循环和自定义函数?
谢谢!

1
你能提供一个 [mcve] 吗? - jpp
df.sort_index(ascending=False)['Close'].rolling(24).min() - Finance_Professional
2个回答

2

df.rolling 可以接受一个字符串频率偏移作为其第一个参数。例如,

import numpy as np
import pandas as pd
np.random.seed(2018)

# Generate a DataFrame with an irregular DatetimeIndex
N = 20
start = np.datetime64('2018-01-01').astype('M8[s]').view('<i8')
end = np.datetime64('2018-02-01').astype('M8[s]').view('<i8')
timestamps = np.random.uniform(start, end, size=N)
timestamps.sort()
index = timestamps.astype('M8[s]')

df = pd.DataFrame(np.random.randint(10, size=(N, 4)), columns=list('OHLC'),
                  index=index)

这将使用2天的窗口大小计算滚动平均值:

df.rolling('2D').mean()

这会使用7天(即一周)的滑动窗口大小计算滚动均值:
df.rolling('7D').mean()

使用1H表示1小时窗口,1D表示1天窗口,7D表示1周窗口。

滚动窗口对应的行数不需要是恒定的。


为了检查上述代码是否产生了期望的结果,请确认df.rolling('7D').mean()的最后两行。

In [91]: df.rolling('7D').mean().tail(2)
Out[91]: 
                            O         H    L         C
2018-01-30 05:22:18  4.285714  3.000000  5.0  3.428571
2018-01-31 23:45:18  3.833333  2.833333  4.5  3.166667

最后一行对应于对这个7天的DataFrame取平均值:

In [93]: end = df.index[-1]; window = df.loc[end-pd.Timedelta(days=7):end]; window
Out[93]: 
                     O  H  L  C
2018-01-25 21:17:07  1  2  1  2
2018-01-26 22:48:38  6  0  3  1
2018-01-28 08:28:04  0  8  7  5
2018-01-29 02:48:53  8  0  2  3
2018-01-30 05:22:18  6  0  8  8
2018-01-31 23:45:18  2  7  6  0

In [94]: window.mean()
Out[94]: 
O    3.833333
H    2.833333
L    4.500000
C    3.166667
dtype: float64

window.mean()函数返回的数值与df.rolling('7D').mean()结果中最后一行的数值相匹配。

同样地,我们可以通过将参数end = df.index[-2]来确认倒数第二行的结果:

In [95]: end = df.index[-2]; window = df.loc[end-pd.Timedelta(days=7):end]; window
Out[95]: 
                     O  H  L  C
2018-01-23 12:05:33  9  8  9  4
2018-01-24 11:16:36  0  3  5  1
2018-01-25 21:17:07  1  2  1  2
2018-01-26 22:48:38  6  0  3  1
2018-01-28 08:28:04  0  8  7  5
2018-01-29 02:48:53  8  0  2  3
2018-01-30 05:22:18  6  0  8  8

In [96]: window.mean()
Out[96]: 
O    4.285714
H    3.000000
L    5.000000
C    3.428571
dtype: float64

In [99]: window.mean().equals(df.rolling('7D').mean().loc[end])
Out[99]: True

请注意,窗口中实际的行数不同(6与7)。

然而,这并没有回答问题,该问题要求以向前的时间方式使用偏移量计算滚动窗口的方法(因为df.rolling('-7D')不起作用)。我在其他地方找到了答案 - 在下面发布。 - PGlivi

1
根据这个答案,在使用滚动函数之前暂时反转时间序列是有效的。以下是一个使用该方法的示例(可用于任何时间序列、偏移量和聚合函数):
让我们生成一些随机不规则索引的时间序列:
import pandas as pd
import numpy as np
    
length = 15
# generate 15 unique days within 90 days from '2020-01-01'  
dates = np.datetime64('2020-01-01') + np.random.choice(90, size = length, replace = False)
ts = pd.Series(np.random.randint(0,9, size = length), index = dates).sort_index()

In[1]: ts
Out[1]: 
2020-01-04    7
2020-01-10    2
2020-01-12    4
2020-01-19    8
2020-02-04    3
2020-02-05    8
2020-02-07    5
2020-02-19    7
2020-02-24    6
2020-02-25    4
2020-03-01    8
2020-03-04    0
2020-03-14    6
2020-03-15    7
2020-03-28    6
dtype: int32

现在,要在1周的向前偏移范围内找到每周最大值,我们只需要在反转的系列上使用“7D”偏移量的滚动函数,然后将结果再次反转即可:
In[2]: ts[::-1].rolling(window = '7D').max()[::-1]
Out[2]: 
2020-01-04    7.0
2020-01-10    4.0
2020-01-12    4.0
2020-01-19    8.0
2020-02-04    8.0
2020-02-05    8.0
2020-02-07    5.0
2020-02-19    7.0
2020-02-24    8.0
2020-02-25    8.0
2020-03-01    8.0
2020-03-04    0.0
2020-03-14    7.0
2020-03-15    7.0
2020-03-28    6.0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接