Próbuję stworzyć warunkową sumę prowadzącą w Pandasach na podstawie dwóch warunków.

import pandas as pd
ID = [1,1,1,2,2,3,4]
after = ['A','B','B','A','A','B','A']
before = ['A','B','B','A','A','B','A']
df = pd.DataFrame([ID, before,after]).T
df.columns = ['ID','before','after']

Dane wyglądają:

   ID before after
0  1      A     A
1  1      B     B
2  1      B     B
3  2      A     A
4  2      A     A
5  3      B     B
6  4      A     A

Wtedy chcemy spojrzeć, jak długo Identyfikator miał wartość przed jak b, moja próba:

df['time_on_b'] = (df.groupby('before')['ID'].cumcount()+1).where(df['before']=='B',0)

To daje mi:

    ID before after  time_on_b
0  1      A     A          0
1  1      B     B          1
2  1      B     B          2
3  2      A     A          0
4  2      A     A          0
5  3      B     B          3
6  4      A     A          0

Idealne wyjście jest następujące:

   ID before after  time_on_b
0  1      A     A          0
1  1      B     B          1
2  1      B     B          2
3  2      A     A          0
4  2      A     A          0
5  3      B     B          1
6  4      A     A          0

Jak widać, ponieważ zmiany identyfikatora chcę Time_on_B do zresetowania, aby daje mi wartość 1 i nie 3.

3
Adam Warner 8 wrzesień 2017, 20:32

2 odpowiedzi

Najlepsza odpowiedź

Wydaje się, że musisz grupować przez ID, a następnie użyj cumsum, aby policzyć wystąpienia B:

cond = df.before == 'B'
df['time_on_b'] = cond.groupby(df.ID).cumsum().where(cond, 0).astype(int)
df
#  ID   before  after   time_on_b
#0  1        A      A   0
#1  1        B      B   1
#2  1        B      B   2
#3  2        A      A   0
#4  2        A      A   0
#5  3        B      B   1
#6  4        A      A   0
7
Psidom 8 wrzesień 2017, 17:39

Możesz także użyć transform jak

df.groupby('ID').before.transform(lambda x: x.eq('B').cumsum())

0    0
1    1
2    2
3    0
4    0
5    1
6    0
Name: before, dtype: int32

df.assign(time_on_b=df.groupby('ID').before.transform(lambda x: x.eq('B').cumsum()))

   ID before after  time_on_b
0   1      A     A          0
1   1      B     B          1
2   1      B     B          2
3   2      A     A          0
4   2      A     A          0
5   3      B     B          1
6   4      A     A          0
3
piroot 8 wrzesień 2017, 17:49