Suchen Sie in einem NumPy-Array nach Indizes von Elementen, die gleich Null sind


144

NumPy verfügt über die effiziente Funktion / Methode nonzero(), um die Indizes von Nicht-Null-Elementen in einem ndarrayObjekt zu identifizieren . Was ist der effizienteste Weg , um die Indizes der Elemente zu erhalten , die nicht einen Wert von Null hat?

Antworten:


226

numpy.where () ist mein Favorit.

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

16
Ich versuche mich an Python zu erinnern. Warum gibt where()ein Tupel zurück? numpy.where(x == 0)[1]ist außerhalb der Grenzen. Womit ist das Indexarray dann gekoppelt?
Zhubarb

@Zhubarb - Die meisten Verwendungen von Indeces sind Tupel - np.zeros((3,))um beispielsweise einen 3-langen Vektor zu erstellen . Ich vermute, dies soll das Parsen der Parameter vereinfachen. Andernfalls wäre es ärgerlich, so etwas wie np.zeros(3,0,dtype='int16')Versus np.zeros(3,3,3,dtype='int16')zu implementieren.
mtrw

5
Nein. whereGibt ein Tupel von ndarrays zurück, von denen jedes einer Dimension der Eingabe entspricht. In diesem Fall ist die Eingabe ein Array, daher ist die Ausgabe a 1-tuple. Wenn x eine Matrix wäre, wäre es eine 2-tupleund so weiter
Ciprian Tomoiagă

1
Ab Nummer 1.16 wird in der Dokumentationnumpy.where ausdrücklich empfohlen, numpy.nonzerodirekt zu verwenden, anstatt wherenur mit einem Argument aufzurufen .
Jirassimok

@jirassimok Wie benutzt man einen Wert ungleich Null, um Nullen zu finden, wenn die Frage gestellt wird?
mLstudent33

28

Es gibt np.argwhere,

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

Dies gibt alle gefundenen Indizes als Zeilen zurück:

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

23

Sie können nach jeder skalaren Bedingung suchen mit:

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

Dadurch wird das Array als boolesche Maske der Bedingung zurückgegeben.


1
Sie können dies verwenden, um auf die Nullelemente zuzugreifen:a[a==0] = epsilon
Quant Metropolis

16

Sie können es auch verwenden, nonzero()indem Sie es für eine boolesche Maske der Bedingung verwenden, da Falsees sich auch um eine Art Null handelt.

>>> 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])

Es macht genau das Gleiche wie mtrwes ist, aber es hängt mehr mit der Frage zusammen;)


Dies sollte die akzeptierte Antwort sein, da dies die empfohlene nonzeroMethode zur Überprüfung der Bedingungen ist.
Sophros

5

Sie können numpy.nonzero verwenden, um Null zu finden.

>>> 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]))

4

Wenn Sie mit einem eindimensionalen Array arbeiten, gibt es einen syntaktischen Zucker:

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

Dies funktioniert gut, solange ich nur eine Bedingung habe. Was ist, wenn ich nach "x == numpy.array (0,2,7)" suchen möchte? Das Ergebnis sollte Array sein ([1,2,3,5,9]). Aber wie kann ich das bekommen?
MoTSCHIGGE

Sie könnten dies tun mit: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)

1

Ich würde es folgendermaßen machen:

>>> 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])
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.