Was wäre der schnellste Weg, um zu überprüfen, ob ein mehrdimensionales Numpy-Array auf allen Seiten 0 hat?
Für ein einfaches 2D-Beispiel habe ich also:
x = np.random.rand(5, 5)
assert np.sum(x[0:, 0]) == 0
assert np.sum(x[0, 0:]) == 0
assert np.sum(x[0:, -1]) == 0
assert np.sum(x[-1, 0:]) == 0
Während dies für 2D-Fälle in Ordnung ist, ist das Schreiben für höhere Dimensionen etwas mühsam und ich habe mich gefragt, ob es einen cleveren Numpy-Trick gibt, den ich hier verwenden kann, um es effizienter und auch wartbarer zu machen.
np.all (x[:, 0] == 0)
sicherer als die Summe? Der Summentest ist nur dann korrekt, wenn alle Zahlen positiv sind.Antworten:
So geht's:
np.take
macht das gleiche wie "ausgefallene" Indizierung.quelle
numpy.take
macht eine Kopie. Dies kann dazu führen, dass die Leistung schlechter ist als bei Code, der auf einer Ansicht basiert. (Das Timing wäre notwendig, um sicherzugehen - die Effizienz der NumPy-Ansicht ist manchmal seltsam.)len(x.shape)
kann einfacher geschrieben werden alsx.ndim
.all
Kurzschluss. Sie können die Klammern entfernen, um einen Generatorausdruck zu verwenden, der dieall
Rückgabe ermöglicht , sobald ein einzelnernumpy.all
Aufruf zurückgegeben wirdFalse
.Hier ist eine Antwort, die tatsächlich die Teile des Arrays untersucht, an denen Sie interessiert sind, und keine Zeit damit verschwendet, eine Maske von der Größe des gesamten Arrays zu erstellen. Es gibt eine Python-Level-Schleife, die jedoch kurz ist und deren Iterationen proportional zur Anzahl der Dimensionen anstelle der Größe des Arrays sind.
quelle
not (view[0] == 0).all()
nicht entsprichtview[0].any()
?view[0].any()
würde auch funktionieren. Ich bin mir nicht ganz sicher, welche Auswirkungen das Casting und die Pufferung auf die Effizienz der beiden Optionen haben -view[0].any()
könnte theoretisch schneller implementiert werden, aber ich habe schon seltsame Ergebnisse gesehen und verstehe die damit verbundene Pufferung nicht vollständig.view[0].view(bool).any()
wäre die Hochgeschwindigkeitslösung.argmax
könnte tatsächlichany
die boolesche Ansicht übertreffen . Dieses Zeug wird komisch.argmax
oder ob dieany
Verwendung einer booleschen Ansicht bedeutet, dass die negative Null als ungleich der regulären Null behandelt wird.)Ich habe das Array umgeformt und es dann durchlaufen. Leider geht meine Antwort davon aus, dass Sie mindestens drei Dimensionen haben und bei normalen Matrizen Fehler auftreten. Sie müssten eine spezielle Klausel für 1 & 2-dimensional geformte Arrays hinzufügen. Darüber hinaus wird dies langsam sein, sodass es wahrscheinlich bessere Lösungen gibt.
Welches wird produzieren
Grundsätzlich staple ich alle Maße übereinander und schaue sie dann durch, um ihre Kanten zu überprüfen.
quelle
Vielleicht ist der Ellipsenoperator genau das, wonach Sie suchen, was für viele Dimensionen funktioniert:
quelle
Sie können eine
slice
boolesche Maskierung verwenden, um die Aufgabe zu erledigen:Diese Funktion formt zuerst den "Kern" des Arrays in das Tupel
s
und erstellt dann eine Maske, dieTrue
nur für die angrenzenden Punkte angezeigt wird. Die boolesche Indizierung liefert dann die Grenzpunkte.Arbeitsbeispiel:
Dann erhalten
np.all(borders==0)
Sie die gewünschten Informationen.Hinweis: Dies wird für eindimensionale Arrays unterbrochen, obwohl ich diese als Randfall betrachte. Sie sind wahrscheinlich besser dran, wenn Sie nur die beiden fraglichen Punkte dort überprüfen
quelle
np.arange(15)
nicht enthalten 15.