NumPy: Iterieren über Arrays

Das NumPy-Iteratorobjekt numpy.nditer bietet eine flexible Möglichkeit, auf ein oder mehrere Array-Elemente zuzugreifen.

Die grundlegendste Aufgabe des Iterators ist der Zugriff auf Array-Elemente.

Als Nächstes verwenden wir die Funktion arange(), um ein 2X3-Array zu erstellen, und verwenden nditer, um darüber zu iterieren.

Beispiel

import numpy as np a = np.arange(6).reshape(2,3) print ('Das ursprüngliche Array ist:') print (a) print ('\n') print ('Iteration über die Elemente:') for x in np.nditer(a): print (x, end=", " ) print ('\n')

Das Ausgabeergebnis ist:

原始数组是:
[[0 1 2]
 [3 4 5]]


迭代输出元素:
0, 1, 2, 3, 4, 5, 

Die obigen Beispiele verwenden weder die standardmäßige C- noch die Fortran-Reihenfolge; die gewählte Reihenfolge entspricht dem Speicherlayout des Arrays, um die Zugriffseffizienz zu verbessern. Standardmäßig gilt die Zeilen-Hauptreihenfolge (oder C-Reihenfolge).

Dies spiegelt wider, dass standardmäßig einfach auf jedes Element zugegriffen wird, ohne seine spezifische Reihenfolge zu berücksichtigen. Wir können dies sehen, indem wir über die Transponierte des obigen Arrays iterieren und sie mit der copy-Methode vergleichen, die auf die Array-Transponierte in C-Reihenfolge zugreift, wie im folgenden Beispiel:

Beispiel

import numpy as np a = np.arange(6).reshape(2,3) for x in np.nditer(a.T): print (x, end=", " ) print ('\n') for x in np.nditer(a.T.copy(order='C')): print (x, end=", " ) print ('\n')

Das Ausgabeergebnis ist:

0, 1, 2, 3, 4, 5, 

0, 3, 1, 4, 2, 5, 

Wie aus den obigen Beispielen ersichtlich ist, ist die Durchlaufreihenfolge von a und a.T dieselbe, was bedeutet, dass sie auch dieselbe Speicherreihenfolge im Speicher haben, abera.T.copy(order = 'C')hat ein anderes Durchlaufergebnis, weil seine Speichermethode sich von den beiden vorherigen unterscheidet und standardmäßig zeilenweise darauf zugegriffen wird.

Steuern der Durchlaufreihenfolge

  • for x in np.nditer(a, order='F'):Fortran-Reihenfolge, d. h., spaltenweise Reihenfolge;
  • for x in np.nditer(a.T, order='C'):C-Reihenfolge, d. h., zeilenweise Reihenfolge;

Beispiel

import numpy as np a = np.arange(0,60,5) a = a.reshape(3,4) print ('Das ursprüngliche Array ist:') print (a) print ('\n') print ('Die Transponierte des ursprünglichen Arrays ist:') b = a.T print (b) print ('\n') print ('In C-Reihenfolge:') c = b.copy(order='C') print (c) for x in np.nditer(c): print (x, end=", " ) print ('\n') print ('In F-Reihenfolge:') c = b.copy(order='F') print (c) for x in np.nditer(c): print (x, end=", " )

Das Ausgabeergebnis ist:

原始数组是:
[[ 0  5 10 15]
 [20 25 30 35]
 [40 45 50 55]]


原始数组的转置是:
[[ 0 20 40]
 [ 5 25 45]
 [10 30 50]
 [15 35 55]]


以 C 风格顺序排序:
[[ 0 20 40]
 [ 5 25 45]
 [10 30 50]
 [15 35 55]]
0, 20, 40, 5, 25, 45, 10, 30, 50, 15, 35, 55, 

以 F 风格顺序排序:
[[ 0 20 40]
 [ 5 25 45]
 [10 30 50]
 [15 35 55]]
0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55,

Sie können das nditer-Objekt zwingen, eine bestimmte Reihenfolge zu verwenden, indem Sie sie explizit festlegen:

Beispiel

import numpy as np a = np.arange(0,60,5) a = a.reshape(3,4) print ('Das ursprüngliche Array ist:') print (a) print ('\n') print ('In C-Reihenfolge:') for x in np.nditer(a, order = 'C'): print (x, end=", " ) print ('\n') print ('In F-Reihenfolge:') for x in np.nditer(a, order = 'F'): print (x, end=", " )

Das Ausgabeergebnis ist:

原始数组是:
[[ 0  5 10 15]
 [20 25 30 35]
 [40 45 50 55]]


以 C 风格顺序排序:
0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 

以 F 风格顺序排序:
0, 20, 40, 5, 25, 45, 10, 30, 50, 15, 35, 55,

Ändern von Array-Elementwerten

Das nditer-Objekt hat einen weiteren optionalen Parameter, op_flags. Standardmäßig behandelt nditer das zu durchlaufende Array als schreibgeschütztes Objekt. Um die Werte von Array-Elementen während der Iteration über das Array zu ändern, müssen Sie den Modus readwrite oder writeonly angeben.

Beispiel

import numpy as np a = np.arange(0,60,5) a = a.reshape(3,4) print ('Das ursprüngliche Array ist:') print (a) print ('\n') for x in np.nditer(a, op_flags=['readwrite']): x[...]=2*x print ('Das geänderte Array ist:') print (a)

Das Ausgabeergebnis ist:

原始数组是:
[[ 0  5 10 15]
 [20 25 30 35]
 [40 45 50 55]]


修改后的数组是:
[[  0  10  20  30]
 [ 40  50  60  70]
 [ 80  90 100 110]]

Verwenden einer externen Schleife

Der Konstruktor der nditer-Klasse hat einen flags-Parameter, der die folgenden Werte akzeptieren kann:

Parameter Beschreibung
c_index Kann den Index in C-Reihenfolge verfolgen
f_index Kann den Index in Fortran-Reihenfolge verfolgen
multi_index Kann einen Indextyp pro Iteration verfolgen
external_loop Der angegebene Wert ist ein eindimensionales Array mit mehreren Werten und kein nulldimensionales Array

Im folgenden Beispiel durchläuft der Iterator entsprechend jeder Spalte und kombiniert sie zu einem eindimensionalen Array.

Beispiel

import numpy as np a = np.arange(0,60,5) a = a.reshape(3,4) print ('Das ursprüngliche Array ist:') print (a) print ('\n') print ('Das modifizierte Array ist:') for x in np.nditer(a, flags = ['external_loop'], order = 'F'): print (x, end=", " )

Das Ausgabeergebnis ist:

原始数组是:
[[ 0  5 10 15]
 [20 25 30 35]
 [40 45 50 55]]


修改后的数组是:
[ 0 20 40], [ 5 25 45], [10 30 50], [15 35 55],

Broadcasting-Iteration

Wenn zwei Arrays broadcastfähig sind, kann das nditer-Kombinationsobjekt gleichzeitig über sie iterieren. Angenommen, Array a hat die Dimensionen 3X4 und Array b hat die Dimensionen 1X4, dann wird der folgende Iterator verwendet (Array b wird auf die Größe von a gebroadcastet).

Beispiel

import numpy as np a = np.arange(0,60,5) a = a.reshape(3,4) print ('Das erste Array ist:') print (a) print ('\n') print ('Das zweite Array ist:') b = np.array([1, 2, 3, 4], dtype = int) print (b) print ('\n') print ('Das modifizierte Array ist:') for x,y in np.nditer([a,b]): print ("%d:%d" % (x,y), end=", " )

Das Ausgabeergebnis ist:

第一个数组为:
[[ 0  5 10 15]
 [20 25 30 35]
 [40 45 50 55]]


第二个数组为:
[1 2 3 4]


修改后的数组为:
0:1, 5:2, 10:3, 15:4, 20:1, 25:2, 30:3, 35:4, 40:1, 45:2, 50:3, 55:4,
Andere Erweiterungen