I don't know whether it's the best answer but I tried to create my own logic to solve this problem.
1) Get the index of rows where the action is done:
m = df.groupby(['id'])['action'].transform(list).eq('DONE')
idx = df[m].index.values.tolist()
df[m]:
id action
4 10 DONE
9 10 DONE
idx:
[4, 9]
2) groupby ID and index of all the rows where Action is either CREATED or UPDATED
n = df.groupby(['id'])['action'].transform(list).str.contains('CREATED|UPDATED', case=False)
n_idx = df[n].index
df[n]:
id action
0 10 CREATED
6 10 UPDATED
7 777 CREATED
n_idx:
Int64Index([0, 6, 7], dtype='int64')
3) Fill new column "check" with empty string:
df['check'] = ''
4) Now you have 2 indexes one is for DONE and another is for CREATED/UPDATED.
Now you have to check if previous rows having any CREATED/UPDATED keeping in mind that they should have the same id.
ix = [0] + idx # <-- [0, 4, 9]
for a in list(zip(ix, ix[1:])): # <--- will create range (0,4), (4,9)
for j in (n_idx):
if j in range(a[0], a[1]): # <--- compare if CREATED/UPDATED indexes fall in this range. (checking previous row) and break if get any of them
if (df.iloc[a[1]].id==df.iloc[j].id): # <-- check for id
df.loc[a[1],'check'] = df.loc[j,'action'][0] # <--- assign Action
break
Final Output:
df:
id action check
0 10 CREATED
1 10 111
2 10 222
3 10 333
4 10 DONE C
5 10 222
6 10 UPDATED
7 777 CREATED
8 10 333
9 10 DONE U
FULL CODE:
m = df.groupby(['id'])['action'].transform(list).eq('DONE')
idx = df[m].index.values.tolist()
n = df.groupby(['id'])['action'].transform(list).str.contains('CREATED|UPDATED', case=False)
n_idx = df[n].index
ix = [0] + idx
df['check'] = ''
for a in list(zip(ix, ix[1:])):
for j in (n_idx):
if (j in range(a[0], a[1]+1)) and (df.iloc[a[1]].id==df.iloc[j].id):
df.loc[a[1],'check'] = df.loc[j,'action'][0]
break
Sample Data with result:
id action check
0 10 CREATED
1 10 111
2 10 DONE C
3 10 333
4 10 DONE
5 10 222
6 10 UPDATED
7 777 CREATED
8 777 DONE C
9 10 DONE
id action check
0 10 CREATED
1 10 111
2 10 DONE C
3 10 333
4 777 UPDATED
5 10 222
6 10 UPDATED
7 777 CREATED
8 777 DONE U
9 10 DONE
DONEvalues perid?