Encuentra índices de elementos iguales a cero en una matriz NumPy

144

NumPy tiene la función / método eficiente nonzero()para identificar los índices de elementos distintos de cero en un ndarrayobjeto. ¿Cuál es la forma más eficiente para obtener los índices de los elementos que hacer tener un valor de cero?

gotgenes
fuente

Respuestas:

226

numpy.where () es mi favorito.

>>> x = numpy.array([1,0,2,0,3,0,4,5,6,7,8])
>>> numpy.where(x == 0)[0]
array([1, 3, 5])
mtrw
fuente
16
Estoy tratando de recordar Python. ¿Por qué where()devuelve una tupla? numpy.where(x == 0)[1]Está fuera de los límites. ¿a qué se acopla la matriz de índice entonces?
Zhubarb
@Zhubarb: la mayoría de los usos de indeces son tuplas, np.zeros((3,))por ejemplo , para hacer un vector de 3 longitudes. Sospecho que esto es para facilitar el análisis de los parámetros. De lo contrario, algo como np.zeros(3,0,dtype='int16')versus np.zeros(3,3,3,dtype='int16')sería molesto de implementar.
mtrw
55
No. wheredevuelve una tupla de ndarrays, cada una de ellas correspondiente a una dimensión de la entrada. en este caso, la entrada es una matriz, por lo que la salida es a 1-tuple. Si x fuera una matriz, sería una 2-tuple, y así sucesivamente
Ciprian Tomoiagă
1
A partir de 1.16 numpy, la documentación paranumpy.where recomienda específicamente utilizar numpy.nonzerodirectamente en lugar de llamar wherecon un solo argumento.
jirassimok
@jirassimok, ¿cómo se usa distinto de cero para encontrar ceros cuando se hace la pregunta?
mLstudent33
28

Hay np.argwhere,

import numpy as np
arr = np.array([[1,2,3], [0, 1, 0], [7, 0, 2]])
np.argwhere(arr == 0)

que devuelve todos los índices encontrados como filas:

array([[1, 0],    # Indices of the first zero
       [1, 2],    # Indices of the second zero
       [2, 1]],   # Indices of the third zero
      dtype=int64)
MSeifert
fuente
23

Puede buscar cualquier condición escalar con:

>>> a = np.asarray([0,1,2,3,4])
>>> a == 0 # or whatver
array([ True, False, False, False, False], dtype=bool)

Lo que devolverá la matriz como una máscara booleana de la condición.

nate c
fuente
1
Puede usar esto para acceder a los elementos cero:a[a==0] = epsilon
Quant Metropolis
17

También puede usarlo nonzero()al usarlo en una máscara booleana de la condición, porque Falsetambién es una especie de cero.

>>> x = numpy.array([1,0,2,0,3,0,4,5,6,7,8])

>>> x==0
array([False, True, False, True, False, True, False, False, False, False, False], dtype=bool)

>>> numpy.nonzero(x==0)[0]
array([1, 3, 5])

Está haciendo exactamente lo mismo mtrw, pero está más relacionado con la pregunta;)

Dusch
fuente
Esta debería ser la respuesta aceptada, ya que es el uso recomendado del nonzerométodo para verificar las condiciones.
Sophros
5

Puedes usar numpy.nonzero para encontrar cero.

>>> import numpy as np
>>> x = np.array([1,0,2,0,3,0,0,4,0,5,0,6]).reshape(4, 3)
>>> np.nonzero(x==0)  # this is what you want
(array([0, 1, 1, 2, 2, 3]), array([1, 0, 2, 0, 2, 1]))
>>> np.nonzero(x)
(array([0, 0, 1, 2, 3, 3]), array([0, 2, 1, 1, 0, 2]))
chmnsk
fuente
4

Si está trabajando con una matriz unidimensional, hay un azúcar sintáctico:

>>> x = numpy.array([1,0,2,0,3,0,4,5,6,7,8])
>>> numpy.flatnonzero(x == 0)
array([1, 3, 5])
dvdvck
fuente
Esto funciona bien siempre que tenga una sola condición. ¿Qué sucede si quiero buscar "x == numpy.array (0,2,7)"? El resultado debe ser una matriz ([1,2,3,5,9]). ¿Pero cómo puedo conseguir esto?
MoTSCHIGGE
Puede hacer esto con:numpy.flatnonzero(numpy.logical_or(numpy.logical_or(x==0, x==2), x==7))
Dusch
1
import numpy as np

x = np.array([1,0,2,3,6])
non_zero_arr = np.extract(x>0,x)

min_index = np.amin(non_zero_arr)
min_value = np.argmin(non_zero_arr)
sramij
fuente
1

Lo haría de la siguiente manera:

>>> x = np.array([[1,0,0], [0,2,0], [1,1,0]])
>>> x
array([[1, 0, 0],
       [0, 2, 0],
       [1, 1, 0]])
>>> np.nonzero(x)
(array([0, 1, 2, 2]), array([0, 1, 0, 1]))

# if you want it in coordinates
>>> x[np.nonzero(x)]
array([1, 2, 1, 1])
>>> np.transpose(np.nonzero(x))
array([[0, 0],
       [1, 1],
       [2, 0],
       [2, 1])
Jeril
fuente