我在尝试创建一个新列时遇到了麻烦,该列是基于“信号”列的检查列。如果最后五行(包括最后一行)为1,则将返回1,如果最后五行(包括最后一行)为0,则将返回0,其他所有内容均为check的最后一个值,如下所示: / p>
我有以下数据框:
signal
index
0 1
1 1
2 1
3 1
4 1
5 1
6 0
7 0
8 0
9 0
10 0
11 0
12 0
13 1
14 0
15 1
16 1
17 1
18 1
19 1
我想要这样的东西:
signal check
index
0 1 1
1 1 1
2 1 1
3 1 1
4 1 1
5 1 1
6 0 1
7 0 1
8 0 1
9 0 1
10 0 0
11 0 0
12 0 0
13 1 0
14 0 0
15 1 0
16 1 0
17 1 0
18 1 0
19 1 1
我将不胜感激!
谢谢!
答案 0 :(得分:3)
您要在数据框上使用滚动窗口,后跟fillna
:
def allSame(x):
if (x == 1).all():
return 1.0
elif (x == 0).all():
return 0.0
else:
return np.nan
df['signal'] = df.rolling(5).apply(allSame, raw=False).fillna(method="ffill")
rolling
返回多个元素上的滚动窗口对象(本例中为5)。窗口对象类似于数据框,但不是具有行,而是在原始数据框的行上方具有窗口。我们可以使用其apply
方法将每个滚动窗口转换为一个值,将滚动窗口对象转换为一个数据框。 apply
方法采用的功能可以将ndarray转换为适当的输出值。
这里,我们将{5}分别返回到窗口的5行全部为1或0的函数传递给apply
,否则返回NaN。结果,我们得到一个新的数据框,其值为1、0或NaN。然后,我们在此数据帧上使用fillna
,以第一个前一个1或0值覆盖NaN值。最后,我们将结果数据框合并回原始数据框,从而创建“信号”列。
答案 1 :(得分:3)
尝试rolling.sum
切片df
和ffill
,bfill
df['check'] = df[df.rolling(5).sum().isin([0, 5])].ffill().bfill()
Out[540]:
signal check
index
0 1 1.0
1 1 1.0
2 1 1.0
3 1 1.0
4 1 1.0
5 1 1.0
6 0 1.0
7 0 1.0
8 0 1.0
9 0 1.0
10 0 0.0
11 0 0.0
12 0 0.0
13 1 0.0
14 0 0.0
15 1 0.0
16 1 0.0
17 1 0.0
18 1 0.0
19 1 1.0
如果您希望check
为整数,只需添加链astype(int)
df['check'] = df[df.rolling(5).sum().isin([0, 5])].ffill().bfill().astype(int)