2013-04-12 10 views
22

In Numpy, nonzero(a), where(a) e argwhere(a), con a come array numpy, tutti sembrano restituire gli indici diversi dall'array. Quali sono le differenze tra queste tre chiamate?Differenza tra non zero (a), dove (a) e argwhere (a). Quando usare quale?

  • Sulla argwhere la documentazione dice:

    np.argwhere(a) è lo stesso di np.transpose(np.nonzero(a)).

    Perché un'intera funzione ha appena trasposto l'uscita di nonzero? Quando sarebbe così utile che meriti una funzione separata?

  • E la differenza tra where(a) e nonzero(a)? Non restituirebbero lo stesso identico risultato?

+1

'where' dà la possibilità di tornare da due diversi array, penso che sia la ragione principale per questo semplicemente' nonzero' – askewchan

+1

Mi aspetto che il motivo principale sia storico :), che np.where fa nell'altro caso è fondamentalmente np.choose ... – seberg

risposta

11

nonzero e argwhere entrambi vi darà informazioni su dove nella matrice gli elementi sono True. where funziona nello stesso modo nonzero nella forma che hai postato, ma ha una seconda forma:

np.where(mask,a,b) 

che può essere più o meno pensato come un NumPy "ufunc" versione della espressione condizionale:

a[i] if mask[i] else b[i] 

(con trasmissione appropriata di a e b).

Per quanto riguarda il entrambinonzero e argwhere, sono concettualmente diversi. nonzero è strutturato per restituire un oggetto che può essere utilizzato per l'indicizzazione.Questo può essere più leggero rispetto alla creazione di un intero maschera booleano se gli 0 sono sparse:

mask = a == 0 # entire array of bools 
mask = np.nonzero(a) 

Ora è possibile utilizzare quella maschera di indicizzare altri array, ecc, tuttavia, così com'è, non è molto bello concettualmente a capire quali indici corrispondono a 0 elementi. Ecco dove argwhere entra.

+0

Non capisco le tue ultime dichiarazioni. 'np.nonzero (a)' restituisce una tupla, quindi 'mask.T' non è permesso. 'mask [:, 0]' allo stesso modo non funziona. – Sam

+0

@ Sam: hai ragione. Mi dispiace per quello (Ho sbagliato su ciò che effettivamente restituisce). Il punto però è lo stesso. 'np.argnonzero' è bello avere gli indici che non sono zero. – mgilson

+0

"Questo può essere più leggero di creare un'intera maschera booleana se gli 0 sono sparsi" - ma devi già creare l'intera maschera booleana per alimentarla a "diverso da zero". – user2357112

9

non posso commentare l'utilità di disporre di una funzione di convenienza separata che traspone il risultato di un altro, ma posso commentare where vs nonzero. Nel suo caso d'uso più semplice, lo where è lo stesso di nonzero.

>>> np.where(np.array([[0,4],[4,0]])) 
(array([0, 1]), array([1, 0])) 
>>> np.nonzero(np.array([[0,4],[4,0]])) 
(array([0, 1]), array([1, 0])) 

o

>>> a = np.array([[1, 2],[3, 4]]) 
>>> np.where(a == 3) 
(array([1, 0]),) 
>>> np.nonzero(a == 3) 
(array([1, 0]),) 

where è diverso da nonzero nel caso in cui si desidera raccogliere elementi di matrice da a se una condizione è True e dalla gamma b quando tale condizione è False.

>>> a = np.array([[6, 4],[0, -3]]) 
>>> b = np.array([[100, 200], [300, 400]]) 
>>> np.where(a > 0, a, b) 
array([[6, 4], [300, 400]]) 

Anche in questo caso, non riesco a spiegare perché hanno aggiunto la funzionalità nonzero-where, ma almeno questo spiega come i due sono diversi.

EDIT: Risolto il primo esempio ... la mia logica non era corretta in precedenza

Problemi correlati