Buscando en Numpy

Oct 01 2020

He ordenado el número ascendente si hace abs (arr) en el siguiente código, estoy tratando de buscar el índice donde el signo cambió de negativo a positivo. Escribí este código a continuación, pero por algunas razones, creo que podemos mejorarlo u optimizarlo más. ¿Algún consejo o truco?

import numpy as np
arr = np.array([-1,-2,-3, 4, 5, 6])
_cut_index_1 = np.where(arr > 0)[0][0]
_cut_index_2 = np.where(arr < 0)[0][-1]
arr[_cut_index_1] # output:   4
arr[_cut_index_2] # output:  -3

Respuestas

4 Juho Oct 03 2020 at 00:45

Su solución actual hace dos pasadas sobre la matriz de entrada (las dos invocaciones de np.where) que, como se indicó, parece un desperdicio. Una forma sencilla de resolver el problema es utilizar np.argmaxlo que llevará un tiempo lineal:

import numpy as np
arr = np.array([-1, -2, -3, 4, 5, 6])
np.argmax(arr > 0) # Return (index) 3

En este punto, si podemos suponer (como parece insinuar) que hay una única posición de interés (y / o que solo nos importa la primera, léalo de izquierda a derecha) habremos terminado: solo decrementa uno de la respuesta y tiene el otro punto de corte (pero verifique si estamos en un caso de esquina para no devolver un índice no válido).

Pero, de hecho, si puede asumir con seguridad que la entrada está ordenada, puede evitar hacer un escaneo lineal y ni siquiera leer toda la entrada. Para ello, puede realizar una búsqueda binaria mediante searchsorted . En teoría, esto es más rápido (es decir, logarítmico frente a lineal en el peor de los casos) pero en la práctica esto dependerá del tamaño de la matriz. Es decir, para arreglos lo suficientemente pequeños, un escaneo lineal será más rápido debido a la ubicación de la caché (o, al menos, ese debería ser el caso en los detalles de su hardware).