Я согласен с использованием Cython или numba
для ускорения цикла и обхода только хвоста массива, но если вы хотите попробовать его с чистым numpy
, я бы сказал, что может сделать что-то вроде следующего:
np.argwhere(x[::-1] != 1).ravel()[0]
Переверните массив и возьмите первое не-1 вхождение. Хотя он охватывает весь массив ... так что, вероятно, он не соответствует вашим потребностям.
РЕДАКТИРОВАТЬ: Вот numba
подход для полноты
from numba import jit
@jit
def count_trailing_ones(array):
count = 0
a = array[::-1]
for i in range(array.shape[0]):
if a[i] == 1:
count += 1
else:
return count
Вот эталонный тест, включающий также решения @J ... S и @Kasramvd для массива 800 МБ с парой миллионов трейлинговых. numba
очевидно побеждает, но если вы идете на numpy
Я бы сказал, @J ... S's argmax
является лучшим.
In [102]: %timeit np.argwhere(x[::-1] != 1).ravel()[0]
631 ms ± 1.83 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
In [103]: %timeit np.argmax(x[::-1] != 1)
117 ms ± 417 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
In [104]: %timeit kas(x)
915 ms ± 3.41 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
In [105]: %timeit count_trailing_ones(x)
4.62 ms ± 16.6 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)