Pesquisando no Numpy

Oct 01 2020

Eu classifiquei o número crescente se você fizer abs (arr) no código abaixo, estou tentando pesquisar o índice onde o sinal mudou de negativo para positivo. Escrevi o código abaixo, mas por alguns motivos, acredito que podemos melhorá-lo ou otimizar mais. Quaisquer dicas e truques?

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

Respostas

4 Juho Oct 03 2020 at 00:45

Sua solução atual faz duas passagens sobre o array de entrada (as duas invocações de np.where) que, conforme declarado, parecem um desperdício. Uma maneira simples de resolver o problema é usar o np.argmaxque levará tempo linear:

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

Neste ponto, se pudermos supor (como você parece sugerir) que há uma única posição de interesse (e / ou que só nos importamos com a primeira, leia da esquerda para a direita), estamos prontos: basta diminuir um de a resposta e você tem o outro ponto de corte (mas verifique se estamos em um caso extremo para não retornar um índice inválido).

Mas, na verdade, se você pode assumir com segurança que a entrada está classificada, você pode evitar fazer uma varredura linear e nem mesmo ler a entrada inteira. Para isso, você pode fazer uma pesquisa binária por meio de searchsorted . Teoricamente, isso é mais rápido (ou seja, logarítmico vs. linear no pior caso), mas na prática isso dependerá do tamanho da matriz. Ou seja, para arrays pequenos o suficiente, uma varredura linear será mais rápida devido à localidade do cache (ou, pelo menos, esse deve ser o caso, modulo os detalhes de seu hardware).