This is my DataFrame:
import pandas as pd
df = pd.DataFrame(
{
'a': [10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70],
'b': [1, 1, 1, -1, -1, -2, -1, 2, 2, -2, -2, 1, -2],
}
)
The mask is:
mask = (
(df.b == -2) &
(df.b.shift(1) > 0)
)
Expected output: slicing df up to the first instance of the mask:
a b
0 10 1
1 15 1
2 20 1
3 25 -1
4 30 -1
5 35 -2
6 40 -1
7 45 2
8 50 2
The first instance of the mask is at row 9. So I want to slice the df up to this index.
This is what I have tried. It works but I am not sure if it is the best way:
idx = df.loc[mask.cumsum().eq(1) & mask].index[0]
result = df.iloc[:idx]
>Solution :
You can filter by inverted mask with Series.cummax:
out = df[~mask.cummax()]
print (out)
a b
0 10 1
1 15 1
2 20 1
3 25 -1
4 30 -1
5 35 -2
6 40 -1
7 45 2
8 50 2
How it working:
print (df.assign(mask=mask,
cumax=mask.cummax(),
inv_cummax=~mask.cummax()))
a b mask cumax inv_cummax
0 10 1 False False True
1 15 1 False False True
2 20 1 False False True
3 25 -1 False False True
4 30 -1 False False True
5 35 -2 False False True
6 40 -1 False False True
7 45 2 False False True
8 50 2 False False True
9 55 -2 True True False
10 60 -2 False True False
11 65 1 False True False
12 70 -2 True True False