Aritmetica Ufunc NumPy

Le Ufunc di NumPy sono uno degli strumenti più utili per eseguire operazioni matematiche sugli array in modo rapido, leggibile e molto più comodo rispetto ai classici cicli Python. Se stai iniziando a usare questa libreria, capire come funziona l’aritmetica Ufunc in NumPy è un passaggio fondamentale per lavorare bene con i dati numerici.

In questa guida vedremo come usare le operazioni principali, cioè addizione, sottrazione, moltiplicazione e divisione, con esempi semplici e subito applicabili. L’obiettivo è aiutarti a comprendere non solo la sintassi, ma anche il comportamento concreto delle Ufunc quando agiscono su array di diverse forme e dimensioni.

Come funzionano le Ufunc di NumPy

Il termine Ufunc significa “universal function”. In pratica, si tratta di funzioni pensate per applicare una stessa operazione a tutti gli elementi di uno o più array. Questo approccio rende il codice più pulito, più veloce e anche più naturale da leggere.

In NumPy, molte operazioni aritmetiche possono essere scritte sia con gli operatori classici come +, , * e /, sia con funzioni esplicite come np.add(), np.subtract(), np.multiply() e np.divide(). Le due strade portano spesso allo stesso risultato, ma conoscere le Ufunc ti aiuta a capire meglio la logica interna della libreria.

Per iniziare, importiamo NumPy e creiamo due array numerici:

import numpy as np

a = np.array([10, 20, 30])
b = np.array([1, 2, 3])

Da questo punto in poi, ogni operazione verrà eseguita elemento per elemento. Significa che il primo valore di a verrà combinato con il primo valore di b, il secondo con il secondo, e così via.

Somma tra array con le Ufunc di NumPy

L’addizione è uno degli esempi più immediati per capire il funzionamento delle Ufunc. Se hai due array della stessa lunghezza, NumPy somma ogni coppia di elementi corrispondenti.

Puoi usare la funzione dedicata oppure l’operatore classico:

import numpy as np

a = np.array([10, 20, 30])
b = np.array([1, 2, 3])

risultato = np.add(a, b)
print(risultato)

L’output sarà un array con i valori sommati:

[11 22 33]

Lo stesso risultato si può ottenere anche così:

import numpy as np

a = np.array([10, 20, 30])
b = np.array([1, 2, 3])

risultato = a + b
print(risultato)

Dal punto di vista pratico, np.add() diventa particolarmente interessante quando vuoi scrivere codice più esplicito o concatenare operazioni in contesti un po’ più strutturati. Per chi è alle prime armi, è utile sapere che entrambe le sintassi sono corrette e molto comuni.

Un altro caso frequente è l’addizione tra un array e un numero singolo. NumPy applica il valore a tutti gli elementi:

import numpy as np

a = np.array([10, 20, 30])

risultato = np.add(a, 5)
print(risultato)

Qui entra in gioco un concetto molto importante di NumPy chiamato broadcasting. In termini semplici, il numero 5 viene esteso virtualmente su tutto l’array, senza che tu debba scrivere cicli o creare strutture aggiuntive.

Differenza tra array: sottrazione con NumPy Ufunc

La sottrazione segue la stessa logica dell’addizione. Ogni elemento del primo array viene diminuito del valore corrispondente nel secondo array. Anche in questo caso puoi scegliere tra funzione esplicita e operatore tradizionale.

import numpy as np

a = np.array([10, 20, 30])
b = np.array([1, 2, 3])

risultato = np.subtract(a, b)
print(risultato)

Il risultato sarà:

[ 9 18 27]

Se preferisci una forma più sintetica, puoi scrivere:

import numpy as np

a = np.array([10, 20, 30])
b = np.array([1, 2, 3])

risultato = a - b
print(risultato)

Vale la pena soffermarsi su un dettaglio concreto: nell’aritmetica con le Ufunc, l’ordine degli operandi conta. Sottrarre b da a non è la stessa cosa che sottrarre a da b.

import numpy as np

a = np.array([10, 20, 30])
b = np.array([1, 2, 3])

print(np.subtract(a, b))
print(np.subtract(b, a))

Questa osservazione sembra banale, ma in molti casi reali evita errori di logica, soprattutto quando lavori con differenze tra valori misurati, serie temporali o risultati di confronti numerici.

Prodotto elemento per elemento con NumPy

La moltiplicazione tra array in NumPy, quando usi le Ufunc o l’operatore *, viene eseguita elemento per elemento. Questo è un punto da ricordare bene, perché chi arriva da altri contesti può pensare a una moltiplicazione matriciale, che invece segue regole diverse.

import numpy as np

a = np.array([10, 20, 30])
b = np.array([1, 2, 3])

risultato = np.multiply(a, b)
print(risultato)

L’output sarà:

[10 40 90]

In alternativa:

import numpy as np

a = np.array([10, 20, 30])
b = np.array([1, 2, 3])

risultato = a * b
print(risultato)

Questa operazione è molto usata nell’elaborazione numerica, ad esempio per applicare coefficienti, pesi o fattori di scala a una sequenza di valori. È una delle forme più immediate per trattare dati in modo vettoriale, senza appesantire il codice.

Se invece vuoi moltiplicare tutti gli elementi di un array per uno stesso numero, NumPy lo gestisce in maniera altrettanto lineare:

import numpy as np

a = np.array([10, 20, 30])

risultato = np.multiply(a, 2)
print(risultato)

In questo caso il risultato sarà un array con tutti i valori raddoppiati. È una soluzione semplice ma molto potente, soprattutto quando devi trasformare grandi quantità di dati in poche righe di codice.

Divisione tra array con le universal function di NumPy

La divisione in NumPy si esegue con np.divide() oppure con l’operatore /. Anche qui il comportamento standard è elemento per elemento.

import numpy as np

a = np.array([10, 20, 30])
b = np.array([1, 2, 3])

risultato = np.divide(a, b)
print(risultato)

L’output sarà:

[10. 10. 10.]

Nota un aspetto importante: il risultato della divisione è spesso espresso in formato float, anche quando i numeri iniziali sono interi. È un comportamento normale e molto utile, perché evita la perdita della parte decimale.

Puoi ottenere lo stesso risultato anche in forma abbreviata:

import numpy as np

a = np.array([10, 20, 30])
b = np.array([1, 2, 3])

risultato = a / b
print(risultato)

Quando lavori con la divisione, è bene fare attenzione ai casi in cui il divisore contiene uno zero. NumPy, in queste situazioni, non sempre blocca l’esecuzione con un errore immediato come farebbe Python puro; può invece restituire valori speciali come inf o nan, accompagnati da un avviso.

import numpy as np

a = np.array([10, 20, 30])
b = np.array([2, 0, 5])

risultato = np.divide(a, b)
print(risultato)

Per chi inizia, questo dettaglio è prezioso: controllare i dati prima della divisione aiuta a evitare risultati inattesi e rende il codice più affidabile.

Corsi correlati

Design Pattern per videogiochi

I Design Pattern sono soluzioni a problemi comuni che si incontrano nello sviluppo del software. Nel contesto dei videogiochi, questi pattern possono aiutare a gestire la complessità crescente dei giochi moderni. Sei appassionato di videogiochi? Hai mai pensato a come vengono progettati e sviluppati? Sei curioso di scoprire i segreti dietro la creazione dei tuoi giochi preferiti? Allora sei nel posto giusto! Questo corso è stato progettato per fornirti una solida comprensione dei Design Pattern, strumenti fondamentali per ogni sviluppatore di giochi. Attraverso esempi pratici e realistici, esploreremo insieme come questi pattern possono aiutarti a creare giochi più efficienti, flessibili e mantenibili.

Corso Fondamenti di Python

Python, uno dei linguaggi di programmazione più popolari al mondo, è ampiamente utilizzato da colossi dell’informatica e della tecnologia come Google, la Nasa e Mozilla.
Questo corso sui fondamenti di Python esplorerà le ragioni del suo successo duraturo. Impareremo la potente ed espressiva sintassi di Python, che consente di ottenere risultati impressionanti con poche righe di codice.

Blender Masterclass 2

I paesaggi, in generale, possono risultare intimidatori data la loro complessità, costituita da numerosi elementi che sembrano formare qualcosa di virtualmente infinito. Durante le lezioni di questo corso, ci concentreremo su una scomposizione delle diverse fasi coinvolte nella creazione di una scena, affrontandole una alla volta attraverso passi graduati.

Blender Masterclass 1

In questo corso di Blender 3D, Masha, in collaborazione con Gedemy, vi mostrerà il processo di modellazione, UV mapping, shading, e texture painting di un asset. Una volta apprese le basi, vedremo anche come effettuare il baking delle textures e la preparazione con successivo export della mesh in modo che possa essere utilizzabile all’interno di un qualsiasi altro software.

Crea il tuo account gratuito Gedemy

Gedemy è la prima piattaforma di formazione italiana che ti permette di sviluppare competenze in ambiti come Game Design, Programming, Arte, 3D, Tech, AI e molto altro.