2013-05-29 13 views
10

Ciao Ho un array con X quantità di valori in esso Vorrei localizzare gli indici dei dieci valori più piccoli. In questo collegamento hanno calcolato il massimo efficacemente, How to get indices of N maximum values in a numpy array? ma non posso ancora commentare i collegamenti, quindi dovrò ripubblicare la domanda.Ho bisogno dei valori N minimo (indice) in un array numpy

Non sono sicuro di quali indici è necessario modificare per ottenere il valore minimo e non quello massimo. Questo è il loro codice di

In [1]: import numpy as np 

In [2]: arr = np.array([1, 3, 2, 4, 5]) 

In [3]: arr.argsort()[-3:][::-1] 
Out[3]: array([4, 3, 1]) 

risposta

22

Se si chiama

arr.argsort()[:3] 

che vi darà gli indici dei 3 elementi più piccoli.

array([0, 2, 1], dtype=int64) 

Così, per n, si dovrebbe chiamare

arr.argsort()[:n] 
5

Non garantisco che questo sarà più veloce, ma un migliore algoritmo di sarebbe contare su heapq.

import heapq 
indices = heapq.nsmallest(10,np.nditer(arr),key=arr.__getitem__) 

Questo dovrebbe funzionare in circa O(N) operazioni mentre l'uso di argsort prenderebbe O(NlogN) operazioni. Tuttavia, l'altro è inserito in C altamente ottimizzata, quindi potrebbe comunque funzionare meglio. Per sapere con certezza, è necessario eseguire alcuni test sui dati effettivi.

+0

o sì, funziona anche così. Ho provato ad usarlo prima ma ne mancava un po 'ed è diventato un po' complicato, ma ora funziona grazie:] – astrochris

+0

Funziona anche per me. Tuttavia, nel mio caso è circa 20 volte più lento della soluzione numpy pura – embert

+0

Non penso che funzioni per i float. – darshan

2

Basta non invertire i risultati di ordinamento.

In [164]: a = numpy.random.random(20) 

In [165]: a 
Out[165]: 
array([ 0.63261763, 0.01718228, 0.42679479, 0.04449562, 0.19160089, 
     0.29653725, 0.93946388, 0.39915215, 0.56751034, 0.873, 
     0.17521395, 0.49573607, 0.84587652, 0.73638224, 0.36303797, 
     0.2150837 , 0.51665416, 0.47111993, 0.79984964, 0.89231776]) 

Ordinati:

In [166]: a.argsort() 
Out[166]: 
array([ 1, 3, 10, 4, 15, 5, 9, 14, 7, 2, 17, 11, 16, 8, 0, 13, 18, 
     12, 19, 6]) 

primi dieci:

In [168]: a.argsort()[:10] 
Out[168]: array([ 1, 3, 10, 4, 15, 5, 9, 14, 7, 2]) 
10

Dal momento che questa domanda è stata pubblicata, NumPy ha aggiornato per includere un modo più veloce di selezionare i più piccoli elementi da un array usando argpartition . È stato incluso per la prima volta in Numpy 1.8.

Utilizzando snarly's answer come ispirazione, siamo in grado di trovare rapidamente le k=3 elementi più piccoli:

In [1]: import numpy as np 

In [2]: arr = np.array([1, 3, 2, 4, 5]) 

In [3]: k = 3 

In [4]: ind = np.argpartition(arr, k)[:k] 

In [5]: ind 
Out[5]: array([0, 2, 1]) 

In [6]: arr[ind] 
Out[6]: array([1, 2, 3]) 

Questo verrà eseguito in O (n), perché non ha bisogno di fare una sorta completo. Se avete bisogno di vostre risposte ordinati (Nota: in questo caso l'array di uscita è stata in modo ordinato, ma che non è garantito) è possibile ordinare l'output:

In [7]: sorted(arr[ind]) 
Out[7]: array([1, 2, 3]) 

Questo viene eseguito su O (n + k log k) perché l'ordinamento avviene sull'elenco di output minore.

Problemi correlati