Given a numpy boolean array
arr = np.array([1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1])
I would like to indicate where there are at least n
consecutive true values (from left to right).
For n = 2
:
# True 2x (or more) in a row
# / \ / \
arr = [1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1]
# becomes:
res = [0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0]
# ^-----------^--^-------- A pattern of 2 or more consecutive True's ends at each of these locations
For n = 3
:
# True 3x (or more) in a row
# / \
arr = [1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1]
# becomes:
res = [0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0]
# ^-------- A pattern of 3 or more consecutive True's ends at this location
Is there a pythonic approach to this without using a for loop to iterate over each element? Performance is important here as my application will perform this operation 1000's of times on boolean arrays containing 1000's of elements.
Notes worth mentioning:
- n can be any value above 2
- n-consecutive patterns can appear anywhere in the array; beginning, middle or end.
- The shape of the result array must match that of the original array.
Any help would be very much appreciated.
Benchmarks on answers
fully vectorized by alain-t:
10000 loops, best of 5: 0.138 seconds per loop, worse of 5: 0.149 seconds per loop
pad/shift by mozway:
10000 loops, best of 5: 1.62 seconds per loop, worse of 5: 1.71 seconds per loop
sliding_window_view by kubatucka (with padding by mozway):
10000 loops, best of 5: 1.15 seconds per loop, worse of 5: 1.54 seconds per loop