熊猫滚动总和以过滤信号

时间:2019-08-14 07:42:42

标签: python pandas

我有一个Pandas数据框,当满足某些条件时,我将在其中创建一个名为Signal的列,结果如下:

Index    Data      ... Signal
1        ...             0
2        ...             1
3        ...             1
4        ...             0
5        ...             1
6        ...             0
7        ...             1
8        ...             1

现在,我希望以这样一种方式过滤我的信号列:仅在满足信号条件的情况下才获得信号,但是如果前N行未触发任何信号,则也将得到信号。例如,对于N = 3:

Index    Data      ... Signal    Filtered_Signal
1        ...             0            0
2        ...             1            1
3        ...             1            0
4        ...             0            0
5        ...             1            0
6        ...             0            0
7        ...             1            1
8        ...             1            0

因此,我尝试执行大小为N的滚动窗口,应用sum(),shift(1)以避免在该总和中包含活动行,然后检查该总和是否大于零,这意味着存在前N行中至少有一个信号:

df['Signal'] = np.where((df['data']>=2), 1, 0) # As an example
df['Filtered_Signal'] = df.Signal.rolling(N, min_periods=1).sum().shift(-1)
signals = df.loc[(df['Signal']==1) & (df['Filtered_Signal']<=1)]

尽管如此,它并没有按我预期的那样工作。在我的用例中,Signal列获得了将近900个带有1的条目,但是对于N = 10,在Filtered_Signal中只有1个带有1的条目。滚动似乎无法动态进行,因此它会直接从所有Signal中删除所有不超过N行的Signal条目,从而几乎删除了所有它们。

我可以迭代数据帧并以老式的方式执行此过滤,但是我的问题是:是否有Pythonic(在Pandanic上)实现此目的?

1 个答案:

答案 0 :(得分:1)

我相信您的问题是创建“过滤信号”的方式。似乎使用您的代码的Filtered Signal的值可能比1大得多,这似乎并不是您想要的。如果我正确理解了您的问题,则以下代码可以正常工作:

df['Filtered Signal']=np.where((df.Signal.rolling(N+1,min_periods=1).sum()==1) & (df.Signal.rolling(1,min_periods=1).sum()==1),1,0)
signals=df.loc[(df['Signal']==1) & (df['Filtered Signal']<=1)]

只需用我创建过滤信号的方式替换您发布的第二行。

请注意,我已删除班次,改用N + 1窗口。

如果该解决方案有帮助,请喜欢此答案:)。