141 votes

Numpy: trouver les premier indice de la valeur rapide

Comment puis-je trouver l'index de la première occurrence d'un nombre dans un tableau Numpy? La vitesse est importante pour moi. Je ne suis pas intéressé par les réponses ci-après parce qu'ils numériser l'ensemble du tableau et ne s'arrêtent pas quand ils trouver la première occurrence:

itemindex = numpy.where(array==item)[0][0]
nonzero(array == item)[0][0]

Note 1: aucune réponse de cette question semble pertinente Python: tableau Numpy aider. Est-il une fonction pour renvoyer l'indice de quelque chose dans un tableau?

Note 2: à l'aide d'un C-compilé méthode est préférable à une boucle Python.

63voto

cyborg Points 5463

Il y a une demande de fonctionnalité pour ce prévue pour Numpy 2.0.0: https://github.com/numpy/numpy/issues/2269

12voto

bubu Points 21

Dans le cas de tableaux triés np.searchsorted travaux.

11voto

Rob Reilink Points 41

Vous pouvez convertir une valeur de type boolean tableau à une chaîne Python à l'aide de array.tostring() , puis à l'aide de la méthode find ():

(array==item).tostring().find('\x01')

Ceci implique la copie de données, bien que, depuis le Python cordes doivent être immuable. Un avantage est que vous pouvez également rechercher par exemple une hausse de bord en trouvant \x00\x01

7voto

Brian Larsen Points 619

Je pense que vous avez frappé un problème où une méthode différente et certains a priori de la connaissance de la matrice serait vraiment aider. Le genre de chose où vous avez un X probabilité de trouver votre réponse dans la première Y pour cent des données. Le fractionnement le problème avec l'espoir d'obtenir de la chance alors, faire en python avec une liste imbriquée de compréhension ou de quelque chose.

Écrire une fonction C pour ce faire, la force brute n'est pas trop dur à l'aide de ctypes .

Le code C j'ai bidouillé (index.c):

long index(long val, long *data, long length){
    long ans, i;
    for(i=0;i<length;i++){
        if (data[i] == val)
            return(i);
    }
    return(-999);
}

et le python:

# to compile (mac)
# gcc -shared index.c -o index.dylib
import ctypes
lib = ctypes.CDLL('index.dylib')
lib.index.restype = ctypes.c_long
lib.index.argtypes = (ctypes.c_long, ctypes.POINTER(ctypes.c_long), ctypes.c_long)

import numpy as np
np.random.seed(8675309)
a = np.random.random_integers(0, 100, 10000)
print lib.index(57, a.ctypes.data_as(ctypes.POINTER(ctypes.c_long)), len(a))

et je reçois 92.

Envelopper le python dans une fonction appropriée et là vous allez.

La version C est beaucoup (~20x plus rapide de cette graine (attention je ne suis pas bon avec timeit)

import timeit
t = timeit.Timer('np.where(a==57)[0][0]', 'import numpy as np; np.random.seed(1); a = np.random.random_integers(0, 1000000, 10000000)')
t.timeit(100)/100
# 0.09761879920959472
t2 = timeit.Timer('lib.index(57, a.ctypes.data_as(ctypes.POINTER(ctypes.c_long)), len(a))', 'import numpy as np; np.random.seed(1); a = np.random.random_integers(0, 1000000, 10000000); import ctypes; lib = ctypes.CDLL("index.dylib"); lib.index.restype = ctypes.c_long; lib.index.argtypes = (ctypes.c_long, ctypes.POINTER(ctypes.c_long), ctypes.c_long) ')
t2.timeit(100)/100
# 0.005288000106811523

3voto

Benjamin Points 3269

Vous pouvez utiliser numpy.argmax(array==item). Cela fonctionne parce que le max de tableau==élément est True ou 1, et renvoie le premier indice où cela se produit.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X