检查熊猫数据框的最后几行是否满足条件的最佳方法是什么?

时间:2020-01-18 22:06:25

标签: python pandas dataframe

我在尝试创建一个新列时遇到了麻烦,该列是基于“信号”列的检查列。如果最后五行(包括最后一行)为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

我将不胜感激!

谢谢!

2 个答案:

答案 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切片dfffillbfill

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)