查找满足条件的滚动窗口产品的非重叠实例(5天库存退货)



我有一个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值。

相关内容

最新更新