如何在Pandas数据框中执行循环滚动?

时间:2018-11-13 13:52:38

标签: python pandas for-loop apply rolling-computation

我有3列的pandas df:

        Close   Top_Barrier Bottom_Barrier
0       441.86  441.964112  426.369888
1       448.95  444.162225  425.227108
2       449.99  446.222271  424.285063
3       449.74  447.947051  423.678282
4       451.97  449.879254  423.029413
...
996     436.97  446.468790  426.600543
997     438.16  446.461401  426.599265
998     437.00  446.093899  426.641434
999     437.52  446.024365  426.631635
1000    437.75  446.114093  426.715907

目标: 对于每一行,我需要测试接下来的30行收盘价中的任何一个是否触及(从第0行开始)顶部或底部障碍,例如,从行索引0开始,测试收盘价(441.86)是否大于Top_Barrier(441.96) )或小于Bottom_Barrier(426.36),如果大于Top_Barrier,则返回1;如果小于Bottom_Barrier,则返回-1。否则,循环到下一行,例如,在索引1,收盘价为448.95,但仍在针对索引0的障碍价进行测试,即Top_Barrier为441.96,Bottom_Barrier为426.36。如果收盘价从未触及壁垒,此循环将一直持续到索引29,如果是这样,则返回0。下一个滚动循环从索引1开始直到30,以此类推。

尝试: 我尝试将.rolling.apply与以下功能配合使用,但无法解决错误。只要能达到上述目的,我们很乐意探索其他方法。谢谢!

def tbl_rolling(x):
    start_i = x.index[0]
    for i in range(len(x)):
        # the barrier freeze at index 0
        if x.loc[i, 'Close'] > x.loc[start_i, 'Top_Barrier']:
            return 1
        elif x.loc[i, 'Close'] < x.loc[start_i, 'Bottom_Barrier']:
            return -1
    return 0

然后,以下内容引发IndexingError:索引器过多

test = df.rolling(30).apply(tbl_rolling, raw=False)

1 个答案:

答案 0 :(得分:0)

如果您的数据集不是很大,您可以尝试这样的事情:

df = df.reset_index().assign(key=1)

def f(x):
    cond1 = x['Close_x'] > x['Top_Barrier_y'].max()
    cond2 = x['Close_x'] < x['Bottom_Barrier_y'].min()
    return np.select([cond1,cond2],[1,-1], default=0)[0]

df.merge(df, on='key').query('index_y <= index_x').groupby('index_x').apply(f)

输出:

index_x
0       0
1       1
2       1
3       1
4       1
996     0
997     0
998     0
999     0
1000    0
dtype: int64