Issue
This is my dataframe:
df = pd.DataFrame(
{
'a': [0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0],
'b': [1, -1, -1, -1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1]
}
)
And this is the output that I want. I want to create column c
:
a b c
0 0 1 0
1 0 -1 0
2 1 -1 0
3 1 -1 0
4 1 1 1
5 1 -1 1
6 0 1 0
7 0 1 0
8 0 -1 0
9 1 1 1
10 1 1 1
11 1 -1 1
12 0 1 0
13 0 1 0
14 1 -1 0
15 1 -1 1
16 0 1 0
This is basically an extension to this post. The highlighted rows below summarize the way that this needs to be done.
First of all in column a
, groups are created by streak of 1s and one row after the streak ends. The highlighted rows in column a
are these groups. The solution for this step is here.
Now what I need is to check column b
for each group in a
. Find the first value that is 1 in b
for each group. And then any value that comes before this becomes 0. This is how column c
is created.
For example for first group in a
, the first value that column b
is 1 is row number 4
. The previous values in that group becomes 0. And the result is the first highlighted group in column c
.
Note that if for a group, all the values in b
are NOT 1, the corresponding group in c
will become all 0s.
This is what I have tried but I can't find the complete solution:
g = df.loc[::-1, 'a'].eq(0).cumsum()
x = df.groupby(g).filter(lambda x: x.b.iloc[0] == 1)
Solution
A variation of the linked answer using groupby.cummax
on df['b'].eq(1)
and an intermediate mask derived from the grouper:
m = df.loc[::-1, 'a'].eq(0)
g = m.cumsum()
df['c'] = np.where(df['b'].eq(1).groupby(g).cummax() & ~m, 1, 0)
Output and intermediates:
a b c m ~m cummax cummax&~m
0 0 1 0 True False True False
1 0 -1 0 True False False False
2 1 -1 0 False True False False
3 1 -1 0 False True False False
4 1 1 1 False True True True
5 1 -1 1 False True True True
6 0 1 0 True False True False
7 0 1 0 True False True False
8 0 -1 0 True False False False
9 1 1 1 False True True True
10 1 1 1 False True True True
11 1 -1 1 False True True True
12 0 1 0 True False True False
13 0 1 0 True False True False
14 1 -1 0 False True False False
15 1 1 1 False True True True
16 0 1 0 True False True False
Answered By - mozway
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.