Löschen von Zeilen im Numpy-Array

86

Ich habe ein Array, das so aussehen könnte:

ANOVAInputMatrixValuesArray = [[ 0.96488889, 0.73641667, 0.67521429, 0.592875, 
0.53172222], [ 0.78008333, 0.5938125, 0.481, 0.39883333, 0.]]

Beachten Sie, dass eine der Zeilen am Ende einen Wert von Null hat. Ich möchte jede Zeile löschen, die eine Null enthält, während jede Zeile, die Werte ungleich Null enthält, in allen Zellen beibehalten wird.

Das Array hat jedoch jedes Mal, wenn es gefüllt wird, eine unterschiedliche Anzahl von Zeilen, und die Nullen befinden sich jedes Mal in unterschiedlichen Zeilen.

Ich erhalte die Anzahl der Nicht-Null-Elemente in jeder Zeile mit der folgenden Codezeile:

NumNonzeroElementsInRows    = (ANOVAInputMatrixValuesArray != 0).sum(1)

NumNonzeroElementsInRowsEnthält für das obige Array : [5 4]

Die fünf geben an, dass alle möglichen Werte in Zeile 0 ungleich Null sind, während die vier angeben, dass einer der möglichen Werte in Zeile 1 eine Null ist.

Daher versuche ich, die folgenden Codezeilen zu verwenden, um Zeilen zu finden und zu löschen, die Nullwerte enthalten.

for q in range(len(NumNonzeroElementsInRows)):
    if NumNonzeroElementsInRows[q] < NumNonzeroElementsInRows.max():
        p.delete(ANOVAInputMatrixValuesArray, q, axis=0)

Aus irgendeinem Grund scheint dieser Code nichts zu tun, obwohl viele Druckbefehle darauf hinweisen, dass alle Variablen im Vorfeld des Codes korrekt ausgefüllt zu sein scheinen.

Es muss eine einfache Möglichkeit geben, einfach "jede Zeile zu löschen, die einen Nullwert enthält".

Kann mir jemand zeigen, welchen Code ich schreiben muss, um dies zu erreichen?

MedicalMath
quelle

Antworten:

157

Der einfachste Weg, Zeilen und Spalten aus Arrays zu löschen, ist die numpy.deleteMethode.

Angenommen, ich habe das folgende Array x:

x = array([[1,2,3],
        [4,5,6],
        [7,8,9]])

Gehen Sie folgendermaßen vor, um die erste Zeile zu löschen:

x = numpy.delete(x, (0), axis=0)

Gehen Sie folgendermaßen vor, um die dritte Spalte zu löschen:

x = numpy.delete(x,(2), axis=1)

Sie können also die Indizes der Zeilen mit einer 0 finden, sie in eine Liste oder ein Tupel einfügen und dies als zweites Argument der Funktion übergeben.

Jaidev Deshpande
quelle
Vielen Dank! Ich hatte das gleiche Problem und konnte nicht herausfinden, warum ein einfacher Anruf numpy.delete(x, index)nicht funktionierte.
Antimon
6
Beachten Sie, dass die numpy delete () -Dokumente angeben, dass "häufig die Verwendung einer booleschen Maske vorzuziehen ist", da ein neues Array zurückgegeben wird - ein Beispiel finden Sie unter diesem Link
arturomp
1
@arturomp aber die Maske ist zerstörungsfrei. Ist ein Aufruf zum Löschen () zeit- / speicherintensiv?
Nathan
13

Hier ist ein Einzeiler (ja, er ähnelt dem von user333700, ist jedoch etwas unkomplizierter):

>>> import numpy as np
>>> arr = np.array([[ 0.96488889, 0.73641667, 0.67521429, 0.592875, 0.53172222], 
                [ 0.78008333, 0.5938125, 0.481, 0.39883333, 0.]])
>>> print arr[arr.all(1)]
array([[ 0.96488889,  0.73641667,  0.67521429,  0.592875  ,  0.53172222]])

Diese Methode ist übrigens viel, viel schneller als die maskierte Array-Methode für große Matrizen. Bei einer Matrix mit 2048 x 5 ist diese Methode etwa 1000x schneller.

Übrigens war die Methode von user333700 (aus seinem Kommentar) in meinen Tests etwas schneller, obwohl es mich verwirrt, warum.

Justin Peel
quelle
3
"any" kann kurzschließen, sobald der erste wahre Fall erkannt wird, kann es aufhören, während "all" alle Bedingungen überprüfen muss. Also sollte keines ("~" in numpy) im Allgemeinen schneller sein als alle.
Josef
4
@ user333700, beide können kurzschließen, nur zu verschiedenen Dingen. anyKurzschlüsse auf wahr beim ersten festgestellten wahren Fall; allKurzschlüsse nach falsch beim ersten erkannten falschen Fall. In diesem Fall sollte der Kurzschluss ein Unentschieden sein, aber das Extra sollte es meiner Meinung nach nicht langsamer machen.
Justin Peel
5

Dies ähnelt Ihrem ursprünglichen Ansatz und benötigt weniger Speicherplatz als die Antwort von unutbu , aber ich vermute, dass er langsamer sein wird.

>>> import numpy as np
>>> p = np.array([[1.5, 0], [1.4,1.5], [1.6, 0], [1.7, 1.8]])
>>> p
array([[ 1.5,  0. ],
       [ 1.4,  1.5],
       [ 1.6,  0. ],
       [ 1.7,  1.8]])
>>> nz = (p == 0).sum(1)
>>> q = p[nz == 0, :]
>>> q
array([[ 1.4,  1.5],
       [ 1.7,  1.8]])

Übrigens p.delete()funktioniert Ihre Leitung bei mir nicht - ndarraysie hat kein .deleteAttribut.

mtrw
quelle
8
etwas einfacher: p [~ (p == 0) .any (1)] oder expliziter für Zeilen: p [~ (p == 0) .any (1) ,:]
Josef
2

numpy bietet eine einfache Funktion, um genau dasselbe zu tun: Angenommen, Sie haben ein maskiertes Array 'a'. Wenn Sie numpy.ma.compress_rows (a) aufrufen, werden die Zeilen gelöscht, die einen maskierten Wert enthalten. Ich denke, das geht auf diese Weise viel schneller ...

jeps
quelle
1
import numpy as np 
arr = np.array([[ 0.96488889, 0.73641667, 0.67521429, 0.592875, 0.53172222],[ 0.78008333, 0.5938125, 0.481, 0.39883333, 0.]])
print(arr[np.where(arr != 0.)])
Prokhozhii
quelle
-1

Ich könnte zu spät sein, um diese Frage zu beantworten, wollte aber meine Beiträge zum Nutzen der Community teilen. Lassen Sie mich in diesem Beispiel Ihre Matrix 'ANOVA' nennen, und ich gehe davon aus, dass Sie nur versuchen, Zeilen mit Nullen nur in der 5. Spalte aus dieser Matrix zu entfernen.

indx = []
for i in range(len(ANOVA)):
    if int(ANOVA[i,4]) == int(0):
        indx.append(i)

ANOVA = [x for x in ANOVA if not x in indx]
troymyname00
quelle