web-dev-qa-db-de.com

zeilen im numpy-Array löschen

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 Nullwert hat. Ich möchte jede Zeile löschen, die eine Null enthält, während alle Zeilen erhalten bleiben, die Werte ungleich Null in allen Zellen enthalten.

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

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

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

Für das obige Array enthält NumNonzeroElementsInRows: [5 4]

Die Fünf zeigt an, dass alle möglichen Werte in Zeile 0 ungleich Null sind, während die Vier angibt, dass einer der möglichen Werte in Zeile 1 eine Null ist.

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

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

Aber aus irgendeinem Grund scheint dieser Code nichts zu tun, auch wenn viele Druckbefehle darauf hinweisen, dass alle Variablen richtig gefüllt zu sein scheinen und zum Code führen.

Es muss einen einfachen Weg 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?

67
MedicalMath

Die einfachste Methode zum Löschen von Zeilen und Spalten aus Arrays ist die numpy.delete-Methode.

Angenommen, ich habe das folgende Array x:

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

So löschen Sie die erste Zeile:

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

So löschen Sie die dritte Spalte:

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

So können Sie die Indizes der Zeilen finden, die eine 0 enthalten, in eine Liste oder einen Tupel einfügen und diese als zweites Argument der Funktion übergeben.

125

Hier ist ein One-Liner (ja, es ist ähnlich wie bei user333700, aber 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]])

Übrigens ist diese Methode viel, viel schneller als die Masked-Array-Methode für große Matrizen. Für eine 2048 x 5-Matrix ist diese Methode etwa 1000-fach schneller.

Übrigens war die Methode von user333700 (aus seinem Kommentar) in meinen Tests etwas schneller, obwohl sie mir den Grund dafür erschüttert.

13
Justin Peel

Dies ist ähnlich zu Ihrem ursprünglichen Ansatz und benötigt weniger Platz als die Antwort von unutbu , aber ich vermute, dass es langsamer 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 funktioniert Ihre Zeile p.delete() nicht für mich - ndarrays haben kein .delete-Attribut.

4
mtrw

numpy bietet eine einfache Funktion, die genau das gleiche tut: 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 viel schneller auf diese Weise ...

2
jeps
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.)])
0
Prokhozhii