English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
L'oggetto iteratore NumPy numpy.nditer offre un modo flessibile per accedere a un singolo o più elementi di un array.
Il compito più fondamentale dell'iteratore è quello di accedere agli elementi dell'array.
Utilizzeremo la funzione arange() per creare un array 2x3 e iterarlo utilizzando nditer.
import numpy as np a = np.arange(12).reshape(2,6) print('L'array originale è:') print(a) print('\n') print(('Elemento iterativo: ')) for x in np.nditer(a): print(x, end=" ")
Risultato di output:
L'array originale è il seguente: [ 0 1 2 3 4 5] [ 6 7 8 9 10 11] Esegui l'output iterativo degli elementi dell'array come segue: 0 1 2 3 4 5 6 7 8 9 10 11
L'esempio sopra non utilizza l'ordine standard C o Fortran, l'ordine scelto è coerente con la disposizione della memoria dell'array, il che migliora l'efficienza dell'accesso, per default è l'ordine di predominio delle righe (row-major order, o C-order).
Questo riflette il fatto che in condizioni di default è sufficiente accedere a ciascun elemento senza dover considerare il suo ordine specifico. Possiamo vedere questo iterando sull'array di trasposizione sopra menzionato e facendo un confronto con il modo di accedere alla copia della trasposizione dell'array con ordine C, come nell'esempio seguente:
import numpy as np a = np.arange(12).reshape(2,6) per x in np.nditer(a.T): print(x, end=" ") print('\n') per x in np.nditer(a.T.copy(order='C')): print(x, end=" ")
Risultato di output:
0 1 2 3 4 5 6 7 8 9 10 11 0 6 1 7 2 8 3 9 4 10 5 11
dal caso specifico sopra riportato si può notare che l'ordine di scansione di a e a.T è lo stesso, ossia che l'ordine di archiviazione in memoria è anche lo stesso, ma a.T.copy(order = 'C') i risultati della scansione sono diversi, poiché il suo modo di archiviazione non è lo stesso degli altri due, per default è l'accesso per riga.
per x in np.nditer(a, order='F'):Fortran order, è il predominio dell'ordine delle colonne;per x in np.nditer(a.T, order='C'):C order, è il predominio dell'ordine delle righe;
import numpy as np a = np.arange(0,100,5) a = a.reshape(4,5) print('L'array originale è:') print(a) print('\n') print('la trasposizione dell'array originale è:'); b = a.T print(b) print('\n') print('in ordine di stile C:'); c = b.copy(order='C') print(c) per x in np.nditer(c): print(x, end=" ") print('\n') print('in ordine di stile F:'); c = b.copy(order='F') print(c) per x in np.nditer(c): print(x, end=" ")
Risultato di output:
L'array originale è: [[0 5 10 15 20] [25 30 35 40 45] [50 55 60 65 70] [75 80 85 90 95] la trasposizione dell'array originale è: [[0 25 50 75] [5 30 55 80] [10 35 60 85] [15 40 65 90] [20 45 70 95] Ordinato in stile C: [[0 25 50 75] [5 30 55 80] [10 35 60 85] [15 40 65 90] [20 45 70 95] 0 25 50 75 5 30 55 80 10 35 60 85 15 40 65 90 20 45 70 95 Ordinato in stile F: [[0 25 50 75] [5 30 55 80] [10 35 60 85] [15 40 65 90] [20 45 70 95] 0 5 10 15 20 25 30 35 40 45 50 55 60 65 70 75 80 85 90 95
è possibile impostare esplicitamente per costringere l'oggetto nditer ad utilizzare un certo ordine:
import numpy as np a = np.arange(0,100,5) a = a.reshape(4,5) print('L'array originale è:') print(a) print('\n') print('in ordine di stile C:'); per x in np.nditer(a, order = 'C'): print(x, end=", "); print('\n') print('in ordine di stile F:'); per x in np.nditer(a, order = 'F'): print(x, end=" ")
Risultato di output:
L'array originale è: [[0 5 10 15 20] [25 30 35 40 45] [50 55 60 65 70] [75 80 85 90 95] Ordinato in stile C: 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, Ordinato in stile F: 0 25 50 75 5 30 55 80 10 35 60 85 15 40 65 90 20 45 70 95
L'oggetto nditer ha un altro parametro op_flags opzionale. Di default, nditer considera l'array da iterare come un oggetto solo-lettura (read-only). Per modificare i valori degli elementi dell'array durante la scansione, è necessario specificare il modello read-write o write-only.
import numpy as np a = np.arange(0,100,5) a = a.reshape(4,5) print('L'array originale è:') print(a) print('\n') for x in np.nditer(a, op_flags=['readwrite']): x[...]=2*x print('L'array modificato è:') print(a)
Risultato di output:
L'array originale è: [[0 5 10 15 20] [25 30 35 40 45] [50 55 60 65 70] [75 80 85 90 95] L'array modificato è: [[0 10 20 30 40] [0 10 20 30 40] [100 110 120 130 140] [150 160 170 180 190]
Il costruttore della classe nditer ha un parametro flags, che può accettare i seguenti valori:
Parametro | Descrizione |
c_index | Può tracciare l'indice in ordine C |
f_index | Può tracciare l'indice in ordine Fortran |
multi-index | Ogni iterazione può tracciare un tipo di indice |
external_loop | I valori forniti sono array uno-dimensionali con più valori, non array zero-dimensionali |
Nell'esempio seguente, l'iteratore esplora corrispondenti a ciascuna colonna e li combina in un array uno-dimensionale.
import numpy as np a = np.arange(0,100,5) a = a.reshape(4,5) print('L'array originale è:') print(a) print('\n') print('L'array modificato è:') for x in np.nditer(a, flags=['external_loop'], order='F'): print(x, end=" ")
Risultato di output:
L'array originale è: [[0 5 10 15 20] [25 30 35 40 45] [50 55 60 65 70] [75 80 85 90 95] L'array modificato è: [0 25 50 75] [5 30 55 80] [10 35 60 85] [15 40 65 90] [20 45 70 95]
Se due array sono broadcastabili, l'oggetto combinato nditer può iterarli contemporaneamente. Supponiamo che l'array a abbia dimensioni 3x4 e l'array b abbia dimensioni 1x4, allora si utilizza il seguente iteratore (l'array b viene broadcastato alla dimensione di a).
import numpy as np a = np.arange(0, 60, 5) a = a.reshape(3, 4) print('Il primo array è:') print(a) print('\n') print('Il secondo array è:') b = np.array([1, 2, 3, 4], dtype=int) print(b) print('\n') print('L'array modificato è:') for x, y in np.nditer([a, b]): print("%d:%d" % (x, y), end=" ")
Risultato di output:
Il primo array è: [[ 0 5 10 15] [20 25 30 35] [40 45 50 55]] Il secondo array è: [1 2 3 4] L'array modificato è: 0:1, 5:2, 10:3, 15:4, 20:1, 25:2, 30:3, 35:4, 40:1, 45:2, 50:3, 55:4,