Introduciamo il concetto di broadcasting, un concetto fondamentale in NumPy che consente di eseguire operazioni aritmetiche tra array di forme diverse ma compatibili. In pratica, il broadcasting permette a NumPy di estendere automaticamente le dimensioni degli array in modo da renderli compatibili per le operazioni.
Quindi, quando si esegue un’operazione aritmetica su due array, NumPy confronta le loro forme elemento per elemento, partendo dalla destra. Se dunque le dimensioni dei due array non corrispondono, NumPy estende automaticamente le dimensioni degli array più piccoli aggiungendo dimensioni di lunghezza 1 fino a quando entrambi gli array hanno la stessa dimensione lungo ciascuna dimensione.
Il broadcasting dunque consente di scrivere codice più conciso ed efficiente, eliminando la necessità di espandere manualmente gli array per renderli compatibili. Questo rende NumPy uno strumento potente per eseguire operazioni su dati multidimensionali in modo rapido e intuitivo.
Migliora le tue capacità di programmazione Python seguendo i nostri corsi in diretta!
Quando può essere applicato il broadcasting?
Il broadcasting in NumPy può essere applicato quando le dimensioni degli array sono compatibili o possono essere allungate in modo da essere compatibili. In generale funziona secondo le seguenti regole:
- Le dimensioni degli array vengono confrontate da destra verso sinistra.
- Per ogni dimensione, le dimensioni degli array devono essere uguali, oppure una delle dimensioni deve essere 1. Dunque, se le dimensioni non sono uguali e nessuna delle dimensioni è 1, il broadcasting non è possibile e verrà generato un errore.
- Se una delle dimensioni di un array è 1 in una determinata dimensione e l’altra dimensione è maggiore di 1, l’array con la dimensione 1 verrà “trasformato” per avere la stessa dimensione dell’altro array in quella dimensione.
- Se le dimensioni di entrambi gli array sono 1 in una determinata dimensione, la dimensione verrà estesa a quella dimensione dell’array risultante.
N.B. Il broadcasting non può essere applicato direttamente se le dimensioni non sono compatibili per le operazioni aritmetiche. Infatti richiede che le dimensioni degli array siano compatibili o che almeno una delle dimensioni sia 1.
Facciamo un esempio di broadcasting possibile:
import numpy as np
# Array con dimensioni compatibili per il broadcasting
arr1 = np.array([[1, 2, 3], [4, 5, 6]]) # shape: (2, 3)
arr2 = np.array([10, 20, 30]) # shape: (3,)
# Broadcasting possibile: arr2 viene esteso a [(10, 20, 30), (10, 20, 30)]
result = arr1 + arr2
E un esempio di broadcasting non possibile:
import numpy as np
# Array con dimensioni non compatibili per il broadcasting
arr1 = np.array([[1, 2, 3], [4, 5, 6]]) # shape: (2, 3)
arr2 = np.array([10, 20]) # shape: (2,)
# Broadcasting non possibile: le dimensioni non sono compatibili
result = arr1 + arr2 # Genera un errore
Esempio di broadcasting
Vediamo un esempio pratico di operazioni con array di dimensione diversa ma compatibile:
import numpy as np
# Creazione di un array unidimensionale e un array bidimensionale
arr1 = np.array([1, 2, 3])
arr2 = np.array([[4, 5, 6], [7, 8, 9]])
# Addizione con Broadcasting
result_addition = arr1 + arr2
print("Addizione con Broadcasting:")
print(result_addition)
# Sottrazione con Broadcasting
result_subtraction = arr1 - arr2
print("Sottrazione con Broadcasting:")
print(result_subtraction)
# Moltiplicazione con Broadcasting
result_multiplication = arr1 * arr2
print("Moltiplicazione con Broadcasting:")
print(result_multiplication)
# Divisione con Broadcasting
result_division = arr1 / arr2
print("Divisione con Broadcasting:")
print(result_division)
# Potenza con Broadcasting
result_power = arr1 ** arr2
print("Potenza con Broadcasting:")
print(result_power)
Per capire l’output, dobbiamo considerare come avviene il broadcasting tra gli array arr1
e arr2
per ciascuna operazione aritmetica.
Addizione con Broadcasting
Addizione con Broadcasting:
[[ 5 6 7]
[ 8 9 10]]
In questo caso, arr1
viene esteso per corrispondere alla forma di arr2
, diventando:
[[1 2 3]
[1 2 3]]
Quindi l’addizione viene eseguita elemento per elemento tra arr1
e arr2
.
L’output sarà il seguente:
Addizione con Broadcasting:
[[ 5 7 9]
[ 8 10 12]]
Sottrazione con Broadcasting
Anche in questo caso, arr1
viene esteso come nel caso precedente e la sottrazione viene eseguita elemento per elemento.
L’output sarà dunque il seguente:
Sottrazione con Broadcasting:
[[-3 -3 -3]
[-6 -6 -6]]
Moltiplicazione con Broadcasting
Come per le operazioni precedenti, arr1
viene esteso per corrispondere alla forma di arr2
e la moltiplicazione viene eseguita elemento per elemento.
L’output sarà dunque il seguente:
Moltiplicazione con Broadcasting:
[[ 4 10 18]
[ 7 16 27]]
Divisione con Broadcasting
Analogamente alle operazioni precedenti, arr1
viene esteso e la divisione viene eseguita elemento per elemento.
L’output sarà dunque il seguente:
Divisione con Broadcasting:
[[0.25 0.4 0.5 ]
[0.14285714 0.25 0.33333333]]
Potenza con Broadcasting
Anche qui, arr1
viene esteso e la potenza viene calcolata elemento per elemento.
L’output sarà dunque il seguente:
Potenza con Broadcasting:
[[ 1 32 729]
[ 1 256 19683]]
Migliora le tue capacità di programmazione Python seguendo i nostri corsi in diretta!
Compatibilità tra array
Nel caso del broadcasting in NumPy, se si sa che potrebbero verificarsi degli errori a causa di dimensioni non compatibili degli array, utilizzare un blocco try
ed except
può essere un modo per gestire elegantemente queste situazioni.
Ecco di seguito un esempio di come gestire l’eccezione:
import numpy as np
arr1 = np.array([[1, 2, 3], [4, 5, 6]]) # Dimensione: (2, 3)
arr2 = np.array([[7, 8, 9]]) # Dimensione: (1, 2)
try:
result = arr1 + arr2
print("Risultato dell'addizione:", result)
except ValueError as e:
print("Errore durante il broadcasting:", e)
In questo esempio se il broadcasting non è possibile, verrà generato un errore di ValueError
durante l’operazione e verrà stampato un messaggio di errore personalizzato.
Conclusioni
Questo articolo ha fornito una panoramica del concetto di broadcasting in NumPy, spiegando quando può essere applicato e quali sono le regole che lo caratterizzano. In particolare abbiamo visto che consente di eseguire operazioni aritmetiche tra array di forme diverse ma compatibili in modo efficiente e intuitivo, eliminando la necessità di espandere manualmente gli array per renderli compatibili.
È un concetto fondamentale in NumPy che rende il codice più conciso ed efficiente, contribuendo così a una migliore gestione e manipolazione dei dati multidimensionali. Comprendere il broadcasting è essenziale per sfruttare appieno le potenzialità di NumPy nell’analisi numerica e scientifica in Python.
Dunque, il broadcasting rappresenta uno strumento potente per eseguire operazioni su dati multidimensionali in modo rapido e intuitivo, contribuendo così a semplificare e ottimizzare il processo di sviluppo e analisi dei dati in Python.
Alcuni link utili
Indice tutorial sul linguaggio Python
Introduzione alla programmazione ad oggetti
Come definire una classe in Python
Calcolatrice in Python utilizzando le classi
Come aggiungere un numero random in un file che contiene dei numeri