Primera aparición de un valor mayor que el valor existente
Tengo una matriz 1D en numpy y quiero encontrar la posición del índice donde un valor excede el valor en la matriz numpy.
P.ej
aa = range(-10,10)
Encuentre la posición en la que se excede aa
el valor .5
Esto es un poco más rápido (y se ve mejor)
np.argmax(aa>5)
Dado que argmax
se detendrá en la primera True
("En caso de que los valores máximos aparezcan varias veces, se devuelven los índices correspondientes a la primera aparición") y no guarda otra lista.
In [2]: N = 10000
In [3]: aa = np.arange(-N,N)
In [4]: timeit np.argmax(aa>N/2)
100000 loops, best of 3: 52.3 us per loop
In [5]: timeit np.where(aa>N/2)[0][0]
10000 loops, best of 3: 141 us per loop
In [6]: timeit np.nonzero(aa>N/2)[0][0]
10000 loops, best of 3: 142 us per loop
Dado el contenido ordenado de su matriz, existe un método aún más rápido: searchsorted .
import time
N = 10000
aa = np.arange(-N,N)
%timeit np.searchsorted(aa, N/2)+1
%timeit np.argmax(aa>N/2)
%timeit np.where(aa>N/2)[0][0]
%timeit np.nonzero(aa>N/2)[0][0]
# Output
100000 loops, best of 3: 5.97 µs per loop
10000 loops, best of 3: 46.3 µs per loop
10000 loops, best of 3: 154 µs per loop
10000 loops, best of 3: 154 µs per loop
También estaba interesado en esto y comparé todas las respuestas sugeridas con perfplot . (Descargo de responsabilidad: soy el autor de perfplot).
Si sabe que la matriz que está revisando ya está ordenada , entonces
numpy.searchsorted(a, alpha)
es para ti. Es una operación O(log(n)), es decir, la velocidad apenas depende del tamaño de la matriz. Tú no puedes ser más rápido que eso.
Si no sabes nada sobre tu matriz, no te equivocarás
numpy.argmax(a > alpha)
Ya ordenado:
Sin clasificar:
Código para reproducir la trama:
import numpy
import perfplot
alpha = 0.5
numpy.random.seed(0)
def argmax(data):
return numpy.argmax(data > alpha)
def where(data):
return numpy.where(data > alpha)[0][0]
def nonzero(data):
return numpy.nonzero(data > alpha)[0][0]
def searchsorted(data):
return numpy.searchsorted(data, alpha)
perfplot.save(
"out.png",
# setup=numpy.random.rand,
setup=lambda n: numpy.sort(numpy.random.rand(n)),
kernels=[argmax, where, nonzero, searchsorted],
n_range=[2 ** k for k in range(2, 23)],
xlabel="len(array)",
)
In [34]: a=np.arange(-10,10)
In [35]: a
Out[35]:
array([-10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2,
3, 4, 5, 6, 7, 8, 9])
In [36]: np.where(a>5)
Out[36]: (array([16, 17, 18, 19]),)
In [37]: np.where(a>5)[0][0]
Out[37]: 16