Numpy Tutorial - NumPy Array Reshape e Resize

  1. numpy.reshape()
  2. ndarray.reshape()
  3. reshape() Funzione / Metodo di memoria condivisa
  4. numpy.resize()

NumPy ha due funzioni (e anche metodi) per modificare le forme degli array - reshape e resize. Hanno una differenza significativa che sarà il nostro punto focale in questo capitolo.

numpy.reshape()

Iniziamo con la funzione per cambiare la forma dell’array - reshape().

import numpy as np

arrayA = np.arange(8)
# arrayA = array([0, 1, 2, 3, 4, 5, 6, 7])

np.reshape(arrayA, (2, 4))
#array([[0, 1, 2, 3],
#       [4, 5, 6, 7]])

Essa converte un vettore di 8 elementi nell’array della forma di (4, 2). Potrebbe essere eseguito con successo perché la quantità di elementi prima e dopo la rimodellazione è identica. Solleva ValueError se le quantità sono diverse.

In [1]: np.reshape(arrayA, (3, 4))
    ---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
ValueError: cannot reshape array of size 8 into shape (3,4)

Diamo un’occhiata più da vicino all’array rimodellato. La prima riga è i primi 4 dati di arrayA e la seconda riga prende gli ultimi 4. Riempie i dati nell’ordine di riga in questa conversione di rimodellamento.

È necessario modificare il parametro order se si vuole che l’ordine dei dati di riempimento sia di colonna.

In [1]: np.reshape(arrayA, (2, 4), order='F')
Out[1]: array([[0, 2, 4, 6],
        	  [1, 3, 5, 7]])

Il default di order è C che significa leggere o scrivere i dati in ordine di indice simile a C, o in parole semplici, nell’ordine di riga. F significa leggere o scrivere dati in ordine di indice simile a Fortan, o diciamo, nell’ordine di column. Si può fare riferimento alla documentazione ufficiale NumPy per maggiori dettagli sui diversi metodi di indicizzazione.

ndarray.reshape()

Oltre alla funzione reshape, NumPy ha anche il metodo reshape nell’oggetto ndarray. Il metodo ha gli stessi parametri della funzione, ma senza un dato array come parametro.

In [1]: arrayB = arrayA.reshape((2, 4))
    
In [2]: arrayB
Out[2]:	array([[0, 1, 2, 3],
       		[4, 5, 6, 7]])
In [1]: arrayA
Out[2]: array([0, 1, 2, 3, 4, 5, 6, 7])    

Si può vedere, il metodo reshape è simile alla funzione reshape. E si dovrebbe anche essere consapevoli che il metodo ndarray.reshape() non cambia i dati e la forma dell’array originale ma restituisce una nuova istanza ndarray.

reshape() Funzione / Metodo di memoria condivisa

L’array convertito nella funzione o metodo reshape condivide la stessa memoria dell’array originale. Si potrebbe pensare che sia una copia superficiale in Python, dove se si modificano i dati in un array, vengono modificati anche i dati corrispondenti nell’altro array.

In [1]: arrayA = np.arange(8)
    	arrayB = arrayA.reshape((2, 4))
        arrayB
Out[2]:	array([[0, 1, 2, 3],
       		[4, 5, 6, 7]])
In [2]: arrayA[0] = 10
    	arrayA
Out[2]: array([10, 1, 2, 3, 4, 5, 6, 7]) 
In [3]: arrayB    
Out[3]:	array([[10, 1, 2, 3],
       		[4, 5, 6, 7]])    

numpy.resize()

numpy.resize() è un po’ simile a reshape nel senso di conversione della forma. Ma ha alcune differenze significative.

  1. Non ha il parametro order. L’ordine di resize è lo stesso di order='C' in reshape.
  2. Se il numero di elementi dell’array di destinazione non è lo stesso dell’array originale, sarà costretto a ridimensionare ma non a generare errori.

Concentriamoci sulla seconda differenza.

In [1]: arrayA = np.arange(8)
        arrayB = np.resize(arrayA, (2, 4))
Out[1]: array([[0, 1, 2, 3],
       [4, 5, 6, 7]])

Il risultato è lo stesso di quello in reshpae se i numeri degli elementi sono gli stessi.

In [1]: arrayC = np.resize(arrayA, (3, 4))
    	arrayC
Out[1]: array([[0, 1, 2, 3],
       [4, 5, 6, 7],
       [0, 1, 2, 3]])
In [2]: arrayD = np.resize(arrayA, (4, 4))
    	arrayD
Out[2]: array([[0, 1, 2, 3],
       [4, 5, 6, 7],
       [0, 1, 2, 3],
       [4, 5, 6, 7]])

Se il nuovo array ha più righe, ripeterà i dati nell’array originale ma non solleverà l’errore.

In [1]: arrayE = np.resize(arrayA, (2, 2))
		arrayE
Out[1]: array([[0, 1],
       [2, 3]])    
In [2]: np.resize(arrayA, (1,4))
Out[2]: array([[0, 1, 2, 3]])

Se il numero di elementi nella nuova matrice è più piccolo, recupera il numero di elementi di cui ha bisogno per riempire la nuova matrice nell’ordine di riga.

Funzione resize / Memoria metodo

Il nuovo array non condivide la stessa memoria con l’array originale nella funzione/metodo resize. Il cambiamento di dati in un array non è mappato con l’altro.

In [1]: arrayA = np.arange(8)
    	arrayB = arrayA.reshape((2, 4))
        arrayB
Out[2]:	array([[0, 1, 2, 3],
       		[4, 5, 6, 7]])
In [2]: arrayA[0] = 10
    	arrayA
Out[2]: array([10, 1, 2, 3, 4, 5, 6, 7]) 
In [3]: arrayB    
Out[3]:	array([[0, 1, 2, 3],
       		[4, 5, 6, 7]])