提问者:小点点

PANDAS:在A列信号之后,根据B列中出现的第一个off创建列


我有一列的信号为on==1,B列的信号为off==1,其余值为零。

data = {'A': [1, 0, 0, 0, 0, 1, 0],
        'B': [1, 0, 1, 1, 0, 0, 1]}
df = pd.DataFrame.from_dict(data)

我需要创建一个列C,其中:

  • a==1和B==0或1,c=1
  • C=1直到B==1,然后C=0

这里的结果应该是:

df['C'] = [1, 1, 0, 0, 0, 1, 0]

我用了

df.loc[df['A'] == 1, 'C'] = 1

将A==1的行设为1,但我找不到方法,在A上的1信号之后,在B列中得到第一个非零,然后用零替换另一个,直到A中的下一个1。


共2个答案

匿名用户

您可以做mask,用transformidxmax,这里的mask是当A等于1时将B设置为0,因为无论B的值是什么,C都会是1。

df['C']=(df.index<df.B.mask(df.A.eq(1),0).groupby(df.A.cumsum()).transform('idxmax')).astype(int)
df
   A  B  C
0  1  1  1
1  0  0  1
2  0  1  0
3  0  1  0
4  0  0  0
5  1  0  1
6  0  1  0

更新

s=df.B.mask(df.A.eq(1),0)
s=(s==1)&(s.shift(-1)==0)

df['C']=(df.index<s.groupby(df.A.cumsum()).transform('idxmax')).astype(int)
df.loc[df.A==1,'C']=1

匿名用户

大家好,欢迎来到StackOverflow。

对于这种情况,您通常不会使用熊猫,因为C的值取决于前面的行。 而pandas则更多地使用“分割-应用-组合”的方法来进行独立的测量

如果它不是运行时关键的,我可能会为此编写一个简单的旧循环:

In [4]: C = [] 
   ...: signal = 0 
   ...: for _, row in df.iterrows(): 
   ...:     if ((signal == 1) and (row.B == 1)): 
   ...:         signal = 0 
   ...:     elif(row.A == 1):  
   ...:         signal = 1 
   ...:     C.append(signal) 
   ...:                                                                         

In [5]: C                                                                       
Out[5]: [1, 1, 0, 0, 0, 1, 0]

In [6]: df['C'] = C                                                             

In [7]: df                                                                      
Out[7]: 
   A  B  C
0  1  1  1
1  0  0  1
2  0  1  0
3  0  1  0
4  0  0  0
5  1  0  1
6  0  1  0

这不会有很好的性能,但是如果代码仍然“足够快”,那么干净地表达代码的意图是值得的。