我有一个2009年12月31日至今亚马逊收盘价的时间序列。
我试图找到Amzn的5天回报率下降超过15%的例子的数量
Date Open High Low Close Adj Close Volume
2009-12-30 138.399994 138.399994 135.279999 136.490005 136.490005 6913200
2009-12-31 137.089996 137.279999 134.520004 134.520004 134.520004 4523000
## to get the 1-day returns
df['returns'] = df['Close'] / df['Close'].shift(1)
## to get the rolling 5-day performance
df['roll']= pd.rolling_apply(df.returns,5,lambda x : x.prod())
## filter returns -15% or more
df2 = df[df['roll']<.85]
虽然上面输出的是一个5天回报率为-15%或更高的行表,但df2的输出具有重叠的5天窗口。
1( 如何在列表中输出滚动5天窗口作为数据帧中的列=>例如:"2009-12-30"、"2009-12-31"、"2010-1-1"、"2010.-1-2"、"2010-2011-1-3"]
2( 如何删除df2中的重叠周期。如果5天窗口中有任何一天与另一行重叠,请只保留该行中的1天。
我不能100%确定你在问题1中的意思,但如果你想从数据帧索引中提取所有日期并将其放入列表中,你可以使用list(df.index)
。如果你的意思是,你想有一个列,其中包含每个5天滚动窗口中使用的日期,那么这可能不是小事,而且有点麻烦。Pandas不允许你用滚动来计算。然而,这里有一个工作解决方案
def find_dates(df, center=False):
dates = df.index.values
dates_list = np.zeros((dates.shape[0],5), dtype=object)
if center:
for i,r in enumerate([2,1,0,-1,-2]):
dates_list[:,i]=np.roll(dates,r)
nul_dates_numbers = [0,1,len(dates)-1,len(dates)-2]
else:
for i,r in enumerate([4,3,2,1,0]):
dates_list[:,i]=np.roll(dates,r)
nul_dates_numbers = [0,1,2,3]
dates_list = [list(d) if j not in nul_dates_numbers else None for j,d in enumerate(dates_list)]
return dates_list
# make a quick dataframe
index_leters = 'a b c d e f g h i j'
indexes = index_leters.split(' ')
df = pd.DataFrame({'B': list(np.arange(len(indexes)))}, index=indexes)
center = False # can set to False
#apply rolling function
df['roll']= pd.rolling_apply(df.B,5,lambda x : x.prod(), center=center)
# extract index windows (will work on dates)
df['dates'] = find_dates(df, center=center)
2( 假设你有每个日期的数据,那么消除重叠周期的一个简单方法就是对数据帧进行切片,只保留每5行的
## to get the rolling 5-day performance
df['roll']= pd.rolling_apply(df.returns,5,lambda x : x.prod())
df_nonoverlapping = df[::5]
此外,如果您希望将指定给每个窗口的日期作为窗口中的中间元素。即在窗口['2009-12-30',2009-12-31','2010-1-1','2010-1-2','2010-1-3']
中,如果希望日期为'2010-1-1'
,则应使用
df['roll']= pd.rolling_apply(df.returns,5,lambda x : x.prod(), center=True)
按照现在的方式,每个5天窗口的日期索引将设置为最后一个,即本例中的'2010-1-3'
。
最后,您应该注意,您的"roll"列中会有一些NaN值,因为您无法计算数据帧开始和结束时的5天滚动平均值。因此,希望在您的"roll"列中有4个NaN值。