Reputation: 115
I wrote a lambda function to adjust a dataframe like this:
df = pd.DataFrame({'types':['A','A','A','A','A','B','B','B','B','B'],'disruptions':['N','N','Y','N','N','N','N','N','N','N'],'actions':[0,0,1,0,0,0,0,1,0,0],'status':[0,0,0,1,1,0,0,0,1,1],'status_2':[0,0,0,0,1,0,0,0,1,1]})
My goal is to convert the 'status' column into 'status_2'. The logic is: within the same 'types' group, if 'action' is labeled as 1 & 'disruptions' is 'Y', then the next row of 'status_2' will be 0. Otherwise equal to 'status'.
Here is what I have:
df['status_2'] = df.groupby('types').apply(lambda x: 0 if x['disruptions'].shift(1) == 'Y' & x['actions'].shift(1) == 1 else x['status'])
The error is: TypeError: cannot compare a dtyped[float64] array with a scalar of type[bool].
Can someone point out what I'm doing wrong here?
Upvotes: 1
Views: 88
Reputation: 862751
I think you need create mask by groupby
, convert to numpy array
by values
and then use Series.mask
, which for True
values get 0
, another values are untouched:
f = lambda x: (x['disruptions'].shift(1) == 'Y') & (x['actions'].shift(1) == 1)
m = df.groupby('types').apply(f).values
print (m)
[False False False True False False False False False False]
#changed column name for compare
df['status_2_new'] = df['status'].mask(m, 0)
print (df)
actions disruptions status status_2 types status_2_new
0 0 N 0 0 A 0
1 0 N 0 0 A 0
2 1 Y 0 0 A 0
3 0 N 1 0 A 0
4 0 N 1 1 A 1
5 0 N 0 0 B 0
6 0 N 0 0 B 0
7 1 N 0 0 B 0
8 0 N 1 1 B 1
9 0 N 1 1 B 1
Upvotes: 1