Flag only first row where condition is met in a DataFrame

Use Series.shift chained with & for bitwise AND:

df['hit_first'] = df['is_hit'].ne(df['is_hit'].shift()) & df['is_hit']
print (df)
                    vals  is_hit  hit_first
dates                                      
2019-03-27  0.000000e+00   False      False
2019-03-28  3.090170e-01   False      False
2019-03-29  5.877853e-01   False      False
2019-03-30  8.090170e-01   False      False
2019-03-31  9.510565e-01    True       True
2019-04-01  1.000000e+00    True      False
2019-04-02  9.510565e-01    True      False
2019-04-03  8.090170e-01   False      False
2019-04-04  5.877853e-01   False      False
2019-04-05  3.090170e-01   False      False
2019-04-06  1.224647e-16   False      False
2019-04-07 -3.090170e-01   False      False
2019-04-08 -5.877853e-01   False      False
2019-04-09 -8.090170e-01   False      False
2019-04-10 -9.510565e-01    True       True
2019-04-11 -1.000000e+00    True      False
2019-04-12 -9.510565e-01    True      False
2019-04-13 -8.090170e-01   False      False
2019-04-14 -5.877853e-01   False      False
2019-04-15 -3.090170e-01   False      False

I also, think you can do it this way:

df['is_hit'].astype(int).diff() == 1

Output:

dates
2019-03-27    False
2019-03-28    False
2019-03-29    False
2019-03-30    False
2019-03-31     True
2019-04-01    False
2019-04-02    False
2019-04-03    False
2019-04-04    False
2019-04-05    False
2019-04-06    False
2019-04-07    False
2019-04-08    False
2019-04-09    False
2019-04-10     True
2019-04-11    False
2019-04-12    False
2019-04-13    False
2019-04-14    False
2019-04-15    False
Name: is_hit, dtype: bool

Timings:

%timeit df['is_hit'] & (~df['is_hit']).shift(1)
1.13 ms ± 5.63 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

%timeit df['is_hit'].ne(df['is_hit'].shift()) & df['is_hit']
908 µs ± 9.53 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

%timeit df['is_hit'].astype(int).diff() == 1
689 µs ± 8.24 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

My suggestion:

df['hit_first'] = df['is_hit'] & (~df['is_hit']).shift(1)