You can use a rolling window and search that for the values you want:
import numpy as np
arr = np.array([1L, 1L, 1L, 1L, 1L, 1L, 1L, 0L, 0L, 0L, 0L, 3L, 3L, 3L, 2L, 2L, 2L,
2L, 2L, 2L, 1L, 1L, 1L, 1L])
def rolling_window(a, window):
shape = a.shape[:-1] + (a.shape[-1] - window + 1, window)
strides = a.strides + (a.strides[-1],)
return np.lib.stride_tricks.as_strided(a, shape=shape, strides=strides)
match_1_0 = np.all(rolling_window(arr, 2) == [1, 0], axis=1)
match_1_3 = np.all(rolling_window(arr, 2) == [1, 3], axis=1)
all_matches = np.logical_or(match_1_0, match_1_3)
print(np.flatnonzero(all_matches)[-1])
Depending on your arrays, this might be good enough performance-wise. With that said, a less flexible (but simpler) solution might perform better even if it is a loop over indices that you usually want to avoid with numpy...:
for ix in xrange(len(arr) - 2, -1, -1): # range in python3.x
if arr[ix] == 1 and (arr[ix + 1] == 0 or arr[ix + 1] == 3):
return ix
You might even be able to do something like which is probably a bit more flexible than the hard-coded solution above and (I would guess) still probably would out-perform the rolling window solution:
def rfind(haystack, needle):
len_needle = len(needle)
for ix in xrange(len(haystack) - len_needle, -1, -1): # range in python3.x
if (haystack[ix:ix + len_needle] == needle).all():
return ix
Here, you'd do something like:
max(rfind(arr, np.array([1, 0])), rfind(arr, np.array([1, 3])))
And of course, with all of these answers, I haven't actually handled the case where the thing you are searching for isn't present since you didn't specify what you would want for that case...