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
argwheredice 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 .