Come rimodellare gli array NumPy in Python

In questo tutorial imparerai come usare NumPy reshape() per rimodellare gli array NumPy senza modificare i dati originali.

Quando si lavora con gli array Numpy, è possibile che si desideri spesso rimodellare un array esistente in un array di dimensioni diverse. Ciò può essere particolarmente utile quando si trasformano i dati in più passaggi.

E NumPy reshape() ti aiuta a farlo facilmente. Nei prossimi minuti imparerai la sintassi per usare reshape() e anche rimodellare gli array in dimensioni diverse.

Che cos’è il rimodellamento negli array NumPy?

Quando si lavora con le matrici NumPy, potresti prima voler creare una matrice unidimensionale di numeri. E poi rimodellarlo in una matrice con la dimensione desiderata.

Ciò è particolarmente utile quando le dimensioni della nuova matrice non sono note inizialmente o vengono dedotte durante l’esecuzione. Oppure può anche essere possibile che una determinata fase di elaborazione dei dati richieda che l’input abbia una forma specifica.

Ecco dove il rimodellamento torna utile.

Si consideri, ad esempio, l’illustrazione seguente. Abbiamo un vettore, un array unidimensionale di 6 elementi. E possiamo rimodellarlo in matrici di forme 2×3, 3×2, 6×1 e così via.

▶️ Per seguire gli esempi in questo tutorial, devi avere installato Python e NumPy. Se non hai ancora NumPy, dai un’occhiata alla nostra guida all’installazione di NumPy.

Ora puoi procedere e importare NumPy con l’alias np, eseguendo: import numpy as np.

Procediamo ad imparare la sintassi nella prossima sezione.

Sintassi di NumPy reshape()

Ecco la sintassi per usare NumPy reshape():

np.reshape(arr, newshape, order="C"|'F'|'A')
  • arr è un qualsiasi oggetto array NumPy valido. Qui è l’array da rimodellare.
  • newshape è la forma del nuovo array. Può essere un numero intero o una tupla.
  • Quando newshape è un numero intero, l’array restituito è unidimensionale.
  • order si riferisce all’ordine in cui si desidera leggere gli elementi dell’array da rimodellare.
  • Il valore predefinito è ‘C’, il che significa che gli elementi dell’array originale verranno letti in un ordine di indicizzazione simile a C (a partire da 0)
  • ‘F’ sta per indicizzazione simile a Fortran (a partire da 1). E “A” legge gli elementi in un ordine simile a C o tipo Fortran a seconda del layout di memoria dell’array arr.

Quindi cosa restituisce np.reshape()?

Se possibile, restituisce una vista rimodellata dell’array originale. Altrimenti, restituisce una copia dell’array.

Nella riga precedente, abbiamo menzionato che NumPy reshape() proverebbe a restituire una vista quando possibile. Altrimenti, ne restituisce una copia. Procediamo a discutere le differenze tra una vista e una copia.

Visualizza e copia degli array NumPy

Come suggerisce il nome, copy è una copia dell’array originale. E qualsiasi modifica apportata alla copia non influirà sull’array originale.

D’altra parte, vista si riferisce semplicemente alla vista rimodellata dell’array originale. Ciò significa che qualsiasi modifica apportata alla vista influirà anche sull’array originale e viceversa.

Utilizzare NumPy reshape() per rimodellare l’array 1D in array 2D

# 1. Iniziamo creando l’array di esempio utilizzando np.arange().

Abbiamo bisogno di un array di 12 numeri, da 1 a 12, chiamato arr1. Poiché la funzione NumPy arange() esclude l’endpoint per impostazione predefinita, impostare il valore di arresto su 13.

Ora usiamo la sintassi sopra e rimodelliamo arr1 con 12 elementi in una matrice 2D di forma (4,3). Chiamiamo questo arr2 con 4 righe e 3 colonne.

import numpy as np

arr1 = np.arange(1,13)
print("Original array, before reshaping:n")
print(arr1)

# Reshape array
arr2 = np.reshape(arr1,(4,3))
print("nReshaped array:")
print(arr2)

Diamo un’occhiata agli array originali e rimodellati.

Original array, before reshaping:

[ 1  2  3  4  5  6  7  8  9 10 11 12]

Reshaped array:
[[ 1  2  3]
 [ 4  5  6]
 [ 7  8  9]
 [10 11 12]]

Invece di passare l’array come argomento np.reshape(), puoi anche chiamare il metodo .reshape() sull’array originale.

È possibile eseguire dir(arr1) e verranno elencati tutti i possibili metodi e attributi che è possibile utilizzare sull’oggetto array arr1.

dir(arr1)

# Output 
[
...
...
'reshape'
...
..
]

Nella cella di codice sopra, puoi vedere che .reshape() è un metodo valido da utilizzare sull’array NumPy esistente arr1.

▶️ Quindi, puoi anche utilizzare la seguente sintassi semplificata per rimodellare gli array NumPy.

arr.reshape(d0,d1,...,dn)

# where:

# d0, d1,..,dn are the dimensions of the reshaped array

# d0 * d1 * ...* dn = N, the number of elements in arr

Per il resto di questo tutorial, usiamo questa sintassi nei nostri esempi.

#2. Proviamo a rimodellare il nostro vettore a 12 elementi in una matrice 12 x 1.

import numpy as np

arr1 = np.arange(1,13)
print("Original array, before reshaping:n")
print(arr1)

# Reshape array
arr3 = arr1.reshape(12,1)
print("nReshaped array:")
print(arr3)

Nell’output seguente, puoi vedere che l’array è stato rimodellato secondo necessità.

Original array, before reshaping:

[ 1  2  3  4  5  6  7  8  9 10 11 12]

Reshaped array:
[[ 1]
 [ 2]
 [ 3]
 [ 4]
 [ 5]
 [ 6]
 [ 7]
 [ 8]
 [ 9]
 [10]
 [11]
 [12]]

❔ Allora, come controlliamo se abbiamo ottenuto una copia o una vista?

Per verificarlo, puoi chiamare l’attributo di base sull’array restituito.

  • Se l’array è una copia, l’attributo di base sarà None.
  • Se l’array è una vista, l’attributo di base sarà l’array originale.

Verifichiamolo velocemente.

arr3.base
# Output
array([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12])

Come puoi vedere, l’attributo base di arr3 restituisce l’array originale. Ciò significa che abbiamo ricevuto una vista dell’array originale.

#3. Ora, proviamo a rimodellare il vettore in un altro array 2 x 6 valido.

import numpy as np

arr1 = np.arange(1,13)
print("Original array, before reshaping:n")
print(arr1)

# Reshape array
arr4 = arr1.reshape(2,6)
print("nReshaped array:")
print(arr4)

Ed ecco l’output:

Original array, before reshaping:

[ 1  2  3  4  5  6  7  8  9 10 11 12]

Reshaped array:
[[ 1  2  3  4  5  6]
 [ 7  8  9 10 11 12]]

Nella prossima sezione, rimodelliamo arr1 in un array 3D.

Usa NumPy reshape() per rimodellare l’array 1D in array 3D

Per rimodellare arr1 in una matrice 3D, impostiamo le dimensioni desiderate su (1, 4, 3).

import numpy as np

arr1 = np.arange(1,13)
print("Original array, before reshaping:n")
print(arr1)

# Reshape array
arr3D = arr1.reshape(1,4,3)
print("nReshaped array:")
print(arr3D)

Ora abbiamo creato un array 3D con gli stessi 12 elementi dell’array originale arr1.

Original array, before reshaping:

[ 1  2  3  4  5  6  7  8  9 10 11 12]

Reshaped array:
[[[ 1  2  3]
  [ 4  5  6]
  [ 7  8  9]
  [10 11 12]]]

Come eseguire il debug degli errori di valore durante il rimodellamento

Se ricordi la sintassi, il reshaping è valido solo quando il prodotto delle dimensioni è uguale al numero di elementi nell’array.

import numpy as np

arr1 = np.arange(1,13)
print("Original array, before reshaping:n")
print(arr1)

# Reshape array
arr2D = arr1.reshape(4,4)
print("nReshaped array:")
print(arr2D)

Qui, stai cercando di rimodellare un array di 12 elementi in un array 4 × 4 con 16 elementi. L’interprete genera un Value Error, come mostrato di seguito.

Original array, before reshaping:

[ 1  2  3  4  5  6  7  8  9 10 11 12]
-----------------------------------------------------------
ValueError                                
Traceback (most recent call last)
<ipython-input-11-63552bcc8c37> in <module>()
      6 
      7 # Reshape array
----> 8 arr2 = arr1.reshape(4,4)
      9 print("nReshaped array:")
     10 print(arr2)

ValueError: cannot reshape array of size 12 into shape (4,4)

Per evitare tali errori, puoi utilizzare -1 per dedurre automaticamente la forma per una delle dimensioni, in base al numero totale di elementi.

Ad esempio, se si conoscono n – 1 dimensioni in anticipo, è possibile utilizzare -1 per dedurre l’n-esima dimensione nell’array rimodellato.

Se si dispone di un array di 24 elementi e si desidera rimodellarlo in un array 3D. Supponiamo di aver bisogno di 3 righe e 4 colonne. Puoi passare il valore di -1 lungo la terza dimensione.

import numpy as np

arr1 = np.arange(1,25)
print("Original array, before reshaping:n")
print(arr1)

# Reshape array
arr_res = arr1.reshape(4,3,-1)
print("nReshaped array:")
print(arr_res)
print(f"Shape of arr_res:{arr_res.shape}")

Quando esamini la forma della matrice di forme, puoi vedere che la matrice rimodellata ha una forma di 2 lungo la terza dimensione.

Original array, before reshaping:

[ 1  2  3  4  5  6  7  8  9 10 11 12 
13 14 15 16 17 18 19 20 21 22 23 24]

Reshaped array:
[[[ 1  2]
  [ 3  4]
  [ 5  6]]

 [[ 7  8]
  [ 9 10]
  [11 12]]

 [[13 14]
  [15 16]
  [17 18]]

 [[19 20]
  [21 22]
  [23 24]]]
Shape of arr_res:(4, 3, 2)

Ciò è particolarmente utile per appiattire un array. E lo imparerai nella prossima sezione.

Usa NumPy reshape() per appiattire un array

Ci sono momenti in cui è necessario tornare da array N-dimensionali a un array appiattito. Supponiamo di voler appiattire un’immagine in un lungo vettore di pixel.

Codifichiamo un semplice esempio utilizzando i seguenti passaggi:

  • Genera un array di immagini in scala di grigi 3 x 3, img_arr, con pixel nell’intervallo da 0 a 255.
  • Quindi, appiattisci questo img_arr e stampa l’array appiattito, flat_arr.
  • Inoltre, stampa le forme di img_arr e flat_arr per verificare.
img_arr = np.random.randint(0, 255, (3,3))
print(img_arr)
print(f"Shape of img_arr: {img_arr.shape}")
flat_arr = img_arr.reshape(-1)
print(flat_arr)
print(f"Shape of flat_arr: {flat_arr.shape}")

Ecco l’output.

[[195 145  77]
 [ 63 193 223]
 [215  43  36]]
Shape of img_arr: (3, 3)

[195 145  77  63 193 223 215  43  36]
Shape of flat_arr: (9,)

Nella cella di codice sopra, puoi vedere che flat_arr è un vettore 1D di valori di pixel con 9 elementi.

Riassumendo👩‍🏫

È tempo di rivedere rapidamente ciò che abbiamo imparato.

  • Usa np.reshape(arr, newshape) per rimodellare arr nella forma specificata in newshape. newshape è una tupla che specifica le dimensioni dell’array rimodellato.
  • In alternativa, utilizzare arr.reshape(d0, d1, …, dn) per rimodellare arr in modo che abbia la forma d0 x d1 x … x dn
  • Verificare se d0 * d1 * …* dn = N, il numero di elementi nell’array originale, per evitare Errori di valore durante il rimodellamento.
  • Utilizzare -1 per al massimo una dimensione nella nuova forma se si desidera che la dimensione venga dedotta automaticamente.
  • Infine, puoi usare arr.reshape(-1) per appiattire l’array.

Ora che sai come usare NumPy reshape(), scopri come funziona la funzione NumPy linspace().

Se lo desideri, puoi provare gli esempi di codice in Jupyter Notebook. Se stai cercando altri ambienti di sviluppo, consulta la nostra guida sulle alternative a Jupyter.