2015-04-25 17 views
5

löschen Lassen Sie uns sagen, ich habe eine quadratische Matrix als Eingang:Python - NumPy - mehrere Zeilen und Spalten aus einem Array

array([[0, 1, 1, 0], 
     [1, 1, 1, 1], 
     [1, 1, 1, 1], 
     [0, 1, 1, 0]]) 

ich die nonzeros im Array zählen wollen nach Entfernen der Zeilen 2 und 3 und der Spalten 2 und 3. Danach möchte ich das Gleiche für die Zeilen 3 und 4 und die Spalten 3 und 4 tun. Daher sollte der

sein Hier
0 # when removing rows/cols 2 and 3 
3 # when removing rows/cols 3 and 4 

ist die naive Lösung mit np.delete:

import numpy as np 
a = np.array([[0,1,1,0],[1,1,1,1],[1,1,1,1],[0,1,1,0]]) 
np.count_nonzero(np.delete(np.delete(a, (1,2), axis=0), (1,2), axis=1)) 
np.count_nonzero(np.delete(np.delete(a, (2,3), axis=0), (2,3), axis=1)) 

Aber np.delete gibt ein neues Array. Gibt es eine schnellere Methode, bei der Zeilen und Spalten gleichzeitig gelöscht werden? Kann Maskierung verwendet werden? Die documentation auf np.delete lautet:

Oft ist es vorzuziehen, eine boolean Maske zu verwenden.

Wie gehe ich dabei vor? Vielen Dank.

+1

Wenn Sie diese Art von Fragen geben, ist es wichtig, dass die Größen der einzelnen variablen (zB Größe der Matrix zu erklären. , Anzahl der gelöschten Zeilen, usw.), da davon die Qualität eine Menge Antworten ableitet. – Veedrac

+0

@Veedrac Danke! Ich kenne. Ich werde versuchen, in der Zukunft nicht zu vergessen. In diesem Fall war die Anzahl der Zeilen in der quadratischen Matrix nie größer als 10. –

Antwort

5

Statt die Spalten zu löschen und Zeilen, die Sie nicht wollen, ist es einfacher, diejenigen auszuwählen, die Sie wollen. Beachten Sie auch, dass standardmäßig das Zählen von Zeilen und Spalten aus Nullen beginnt. Um Ihr erstes Beispiel bekommen Sie so wollen alle Elemente in Zeilen auszuwählen 0 und 3 und in den Zeilen 0 und 3. Diese advanced indexing erfordert, für die Sie die ix_ utility function verwenden:

In [25]: np.count_nonzero(a[np.ix_([0,3], [0,3])]) 
Out[25]: 0 

Für Ihr zweites Beispiel, Sie wollen Zeilen auszuwählen 0 und 1 und Spalten 0 und 1, die basic slicing mit getan werden kann:

In [26]: np.count_nonzero(a[:2,:2]) 
Out[26]: 3 
+0

'numpy.ix' war genau das, wonach ich suchte. Ich sollte mich hinsetzen und eines Tages die angeschlagene Dokumentation lesen. Vielen Dank! –

+2

Das Durchlesen ganzer Handbücher, nur um obskure, aber nützliche Funktionen zu entdecken, macht nicht viel Spaß. Bessere Arbeit durch einige grundlegende Tutorials, und einige detailliertere über importieren, aber verwirrende Konzepte wie Broadcasting und die über die Indizierung, die ich in meiner Antwort verlinkt habe. –

+0

Die erste beinhaltet immer noch das Kopieren.Beachten Sie, dass, wenn Sie nur 2 Zeilen und Spalten löschen, die eine große Matrix haben, die Summen der 9 Untermatrizen zwischen den gelöschten Zeilen genommen werden können. Diese Scheiben würden keine Kopien beinhalten. – Veedrac

3

Sie müssen Ihr ursprüngliches Array nicht ändern, indem Sie Zeilen/Spalten löschen, um die Anzahl der Elemente ungleich Null zu zählen. Einfach Indizierung verwenden,

a = np.array([[0,1,1,0],[1,1,1,1],[1,1,1,1],[0,1,1,0]]) 
irows, icols = np.indices(a.shape) 
mask = (irows!=2)&(irows!=3)&(icols!=2)&(icols!=3) 
np.count_nonzero(a[mask]) 
+0

Dies ist auch eine gute Lösung, aber das Schreiben einer expliziten Maske für jeden Fall ist keine Option. Danke für die Antwort. –

+1

@ tommy.carstensen Nun könnte man diese Funktion einfach erweitern, indem man die Zeilen-/Spaltennummern übernimmt und eine entsprechende Maske ausgibt. Obwohl ich zustimme, dass, wenn Sie mit der Auswahl der verbleibenden Spalten mit 'np.ix_' leben können, wäre das ein besserer Ansatz. – rth

Verwandte Themen