python - functions - Diferencia entre distinto de cero(a), donde(a) y argwhere(a). ¿Cuándo usar cuál?
numpy python 3.6 windows (2)
En Numpy, nonzero(a)
, where(a)
y argwhere(a)
, con a
matriz numpy, todos parecen devolver los índices distintos de cero de la matriz. ¿Cuáles son las diferencias entre estas tres llamadas?
En el
argwhere
dice la documentación:np.argwhere(a)
es lo mismo quenp.transpose(np.nonzero(a))
.¿Por qué tener una función completa que solo transpone la salida del
nonzero
? ¿Cuándo sería tan útil que merece una función separada?¿Qué hay de la diferencia entre
where(a)
ynonzero(a)
? ¿No devolverían exactamente el mismo resultado?
No puedo comentar sobre la utilidad de tener una función de conveniencia separada que traspone el resultado de otra, pero puedo comentar where
vs nonzero
. En su caso de uso más simple, where
hecho es lo mismo que nonzero
es 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
es diferente de nonzero
de nonzero
en el caso en el que desea seleccionar elementos de la matriz a
si alguna condición es True
y de la matriz b
cuando esa condición es 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]])
Nuevamente, no puedo explicar por qué agregaron la funcionalidad nonzero
a where
, pero al menos esto explica en qué se diferencian los dos.
EDITAR : Se corrigió el primer ejemplo ... mi lógica era incorrecta anteriormente
nonzero
y argwhere
ambos le brindan información sobre en qué parte de la matriz los elementos son True
. where
funciona de la misma forma que nonzero
es nonzero
en el formulario que ha publicado, pero tiene un segundo formulario:
np.where(mask,a,b)
que se puede considerar a grandes rasgos como una versión numpy "ufunc" de la expresión condicional:
a[i] if mask[i] else b[i]
(Con difusión adecuada de a
y b
).
En cuanto a tener un punto nonzero
y argwhere
, son conceptualmente diferentes. nonzero
está estructurado para devolver un objeto que se puede usar para la indexación. Esto puede ser más liviano que crear una máscara booleana completa si los 0 son escasos:
mask = a == 0 # entire array of bools
mask = np.nonzero(a)
Ahora puede usar esa máscara para indexar otras matrices, etc. Sin embargo, como es, no es muy bueno conceptualmente averiguar qué índices corresponden a 0 elementos. Ahí es donde entra el argwhere
.