Pandas: How to compute a conditional rolling/accumulative maximum within a group

I would like to achieve the following results in the column condrolmax (based on column close) (conditional rolling/accumulative max) without using a stupidly slow for loop.

Index    close    bool       condrolmax
0        1        True       1
1        3        True       3
2        2        True       3
3        5        True       5
4        3        False      5
5        3        True       3 --> rolling/accumulative maximum reset (False cond above)
6        4        True       4
7        5        False      4
8        7        False      4
9        5        True       5 --> rolling/accumulative maximum reset (False cond above)
10       7        False      5
11       8        False      5
12       6        True       6 --> rolling/accumulative maximum reset (False cond above)
13       8        True       8
14       5        False      8
15       5        True       5 --> rolling/accumulative maximum reset (False cond above)
16       7        True       7
17       15       True       15
18       16       True       16

The code to create this dataframe:

# initialise data of lists.
data = {'close':[1,3,2,5,3,3,4,5,7,5,7,8,6,8,5,5,7,15,16],
        'bool':[True, True, True, True, False, True, True, False, False, True, False,
                False, True, True, False, True, True, True, True],
        'condrolmax': [1,3,3,5,5,3,4,4,4,5,5,5,6,8,8,5,7,15,16]}
 
# Create DataFrame
df = pd.DataFrame(data)

I am sure it is possible to vectorize that (one liner). Any suggestions ?

Thanks again !

Answer

You can set group and then use cummax(), as follows:

# Set group: New group if current row `bool` is True and last row `bool` is False
g = (df['bool'] & (~df['bool']).shift()).cumsum()   

# Get cumulative max of column `close` within the group 
df['condrolmax'] = df.groupby(g)['close'].cummax()

Result:

print(df)

    close   bool  condrolmax
0       1   True           1
1       3   True           3
2       2   True           3
3       5   True           5
4       3  False           5
5       3   True           3
6       4   True           4
7       5  False           5
8       7  False           7
9       5   True           5
10      7  False           7
11      8  False           8
12      6   True           6
13      8   True           8
14      5  False           8
15      5   True           5
16      7   True           7
17     15   True          15
18     16   True          16