Chi conosce Python sa bene che qualunque sia la sua esigenza è molto probabile che ci sia una libreria fatta proprio per tale scopo. Alla fine questo è proprio uno degli aspetti che ha permesso a Python di crescere enormemente negli ultimi anni e diventare uno dei linguaggi di riferimento per la Data Science e non solo.

Nel vasto ecosistema di Python dunque esistono numerosissime librerie, ma tra queste certamente NumPy si distingue come una delle librerie più importanti e ampiamente utilizzate, specialmente nel campo del calcolo scientifico e dell’analisi dei dati. 

Questa libreria fondamentale ha rivoluzionato il modo in cui gli sviluppatori e gli scienziati gestiscono le operazioni matematiche e la manipolazione di array multidimensionali in Python.

Cos’è NumPy: introduzione alla libreria di Python

Possiamo tranquillamente affermare che NumPy, abbreviazione di “Numerical Python”, rappresenta il fondamento dell’ecosistema scientifico di Python. Sviluppata inizialmente come parte del progetto SciPy nel 2005, questa libreria si è evoluta fino a diventare un elemento indispensabile per chiunque lavori con dati numerici in Python. La sua importanza è tale che molte altre librerie popolari come Pandas, Matplotlib e Scikit-learn sono costruite proprio sulle sue fondamenta.

NumPy ha molte caratteristiche che lo rendono così importante ma tra tutte, possiamo dire che la caratteristica più distintiva di NumPy è la sua capacità di gestire array multidimensionali in modo efficiente. Mentre Python standard offre le liste come struttura dati principale per gestire collezioni di elementi, NumPy introduce il concetto di ndarray (n-dimensional array), che sono molto più efficienti in termini di memoria e velocità di elaborazione quando si tratta di operazioni matematiche complesse.

Per comprendere meglio l’importanza di NumPy, consideriamo un esempio pratico. Immaginiamo di dover calcolare la media di un milione di numeri. Utilizzando le liste Python standard, dovremmo iterare attraverso ogni elemento, sommarlo e poi dividere per il numero totale di elementi. Con NumPy, questa operazione può essere eseguita con una singola istruzione, sfruttando l’ottimizzazione del codice C sottostante che rende l’elaborazione significativamente più veloce.

Un altro dei punti caratterizzanti di NumPy infatti è che la sua architettura è stata progettata pensando proprio alle prestazioni. La libreria infatti implementa molte delle sue funzionalità in C e Fortran, linguaggi noti per la loro efficienza nell’elaborazione numerica. Questo significa che quando utilizziamo NumPy, stiamo effettivamente eseguendo codice ottimizzato a basso livello, pur mantenendo la semplicità e la leggibilità tipiche di Python.

Una delle ragioni del successo di NumPy nel campo scientifico è la sua capacità di gestire dati omogenei. In un array NumPy, tutti gli elementi devono essere dello stesso tipo di dati, il che permette un’organizzazione più efficiente della memoria e operazioni più veloci. Questo può sembrare una limitazione rispetto alle liste Python, che possono contenere elementi di tipo diverso, ma in realtà è un vantaggio significativo per le applicazioni scientifiche e di analisi dei dati.

La comunità scientifica ha abbracciato NumPy non solo per le sue prestazioni, ma anche per la sua versatilità. La libreria supporta una vasta gamma di operazioni matematiche e statistiche, dalla semplice aritmetica alle trasformazioni matriciali complesse. 

Proprio come vediamo nel nostro corso su NumPy, è fondamentale comprendere che questa libreria non è solo uno strumento per il calcolo numerico, ma una piattaforma completa per l’analisi dei dati.

A cosa serve NumPy nel calcolo numerico

È evidente da quanto visto fino ad ora che il ruolo di NumPy nel calcolo numerico sia fondamentale. La libreria fornisce infatti strumenti essenziali per una vasta gamma di applicazioni, dalla ricerca scientifica all’apprendimento automatico. Per chi aspira a diventare data scientist, comprendere le capacità di NumPy più che un valore aggiunto è un requisito imprescindibile.

Nel campo del calcolo scientifico, NumPy eccelle nella gestione di operazioni matriciali complesse. La libreria offre un’implementazione efficiente dell’algebra lineare, essenziale per molte applicazioni scientifiche e di ingegneria. Le operazioni come la moltiplicazione matriciale, il calcolo di autovalori e autovettori, e la decomposizione in valori singolari (SVD) sono implementate in modo ottimizzato, rendendo NumPy uno strumento indispensabile per chi lavora con questi concetti matematici.

I principali utilizzi della libreria NumPy

Nell’ambito dell’analisi dei dati e del calcolo scientifico, NumPy si distingue per la sua versatilità e potenza. Un aspetto fondamentale della libreria è la sua capacità di gestire grandi volumi di dati con efficienza. Quando lavoriamo con dataset di dimensioni considerevoli, le strutture dati tradizionali di Python potrebbero risultare poco performanti. NumPy risolve questo problema attraverso l’utilizzo di array ottimizzati, che consentono di elaborare milioni di elementi in frazioni di secondo.

Ovviamente viene da sé che anche nel contesto del Machine Learning, come vediamo nel nostro corso di machine learning, NumPy gioca un ruolo cruciale. La libreria infatti fornisce le fondamenta matematiche necessarie per implementare algoritmi di apprendimento automatico. Ad esempio, quando si lavora con reti neurali, le operazioni matriciali efficienti di NumPy sono essenziali per il calcolo della propagazione in avanti e all’indietro durante l’addestramento del modello.

La manipolazione di immagini è un altro ambito in cui NumPy brilla particolarmente. Un’immagine digitale può essere rappresentata come un array bidimensionale (o tridimensionale nel caso di immagini a colori) di valori numerici. NumPy fornisce strumenti potenti per modificare, trasformare e analizzare questi array di pixel. Operazioni come il ridimensionamento, la rotazione, il filtraggio e la segmentazione delle immagini diventano notevolmente più semplici grazie alle funzioni integrate di NumPy.

 

Funzioni di NumPy: alcuni esempi pratici

Consideriamo innanzitutto l’analisi statistica di un dataset. Supponiamo di avere un array di temperature giornaliere registrate durante un anno. Con NumPy, possiamo facilmente calcolare statistiche descrittive come media, mediana, deviazione standard e quartili con poche righe di codice.

# Calcolo delle statistiche descrittive 
media = np.mean(temperature) 
mediana = np.median(temperature) 
dev_standard = np.std(temperature) 
primo_quartile = np.percentile(temperature, 25) 
terzo_quartile = np.percentile(temperature, 75)

La generazione di numeri casuali è un’altra funzionalità importante di NumPy, particolarmente utile nelle simulazioni e nel machine learning. Il modulo numpy.random fornisce una vasta gamma di distribuzioni probabilistiche, dalla semplice distribuzione uniforme a distribuzioni più complesse come la normale, la binomiale o la di Poisson. Questa capacità è fondamentale per la creazione di dati sintetici, il bootstrapping e la validazione di modelli statistici.

 

Come installare la libreria NumPy su Python

L’installazione di NumPy è un processo relativamente semplice, ma è importante seguire alcuni passaggi fondamentali per garantire una configurazione corretta. Prima di tutto, è necessario avere Python installato sul proprio sistema. NumPy è compatibile con Python 3.x, e si raccomanda di utilizzare la versione più recente stabile di Python per garantire la massima compatibilità e prestazioni.

Guida all’installazione su diversi sistemi operativi

Su sistemi Windows, l’installazione di NumPy può essere effettuata attraverso il gestore di pacchetti pip. È sufficiente aprire il prompt dei comandi e digitare il comando “pip install numpy”. Tuttavia, per gli utenti Windows che lavorano in ambito scientifico, si consiglia spesso di utilizzare distribuzioni Python preconfigurate come Anaconda, che include già NumPy e altre librerie scientifiche essenziali.

Per gli utenti Linux, l’installazione può essere effettuata sia attraverso pip che utilizzando il gestore di pacchetti del sistema operativo. Ad esempio, su Ubuntu, si può installare NumPy utilizzando il comando “sudo apt-get install python3-numpy”. Questa approccio ha il vantaggio di gestire automaticamente le dipendenze a livello di sistema.

Su macOS, l’installazione può essere effettuata utilizzando pip, Homebrew o Anaconda. L’utilizzo di Homebrew (“brew install numpy”) è particolarmente conveniente per gli utenti macOS, in quanto gestisce automaticamente le dipendenze e garantisce una corretta integrazione con il sistema.

Verifica dell’installazione e primo utilizzo

Dopo l’installazione, è importante verificare che NumPy sia stato installato correttamente e sia funzionante. Possiamo farlo aprendo l’interprete Python e importando la libreria:

import numpy as np

print(np.__version__)

 

Questo comando non solo verifica che NumPy sia installato, ma ci mostra anche la versione attualmente in uso. È importante mantenere NumPy aggiornato all’ultima versione stabile per beneficiare delle ottimizzazioni più recenti e delle nuove funzionalità.

Per un primo utilizzo, possiamo creare un semplice array e eseguire alcune operazioni di base:

# Creazione di un array

arr = np.array([1, 2, 3, 4, 5])




# Operazioni matematiche di base

print(arr * 2)  # Moltiplicazione elemento per elemento

print(arr.mean())  # Media

print(arr.sum())  # Somma

 

Questo esempio elementare dimostra già alcune delle caratteristiche fondamentali di NumPy: la creazione di array e l’applicazione di operazioni vettorizzate.

Le principali funzioni di NumPy per Python

NumPy offre un’ampia gamma di funzioni che coprono praticamente ogni aspetto del calcolo numerico. Comprendere queste funzioni è essenziale per sfruttare appieno il potenziale della libreria. Le funzioni di NumPy possono essere categorizzate in diverse aree principali, ciascuna dedicata a specifici tipi di operazioni matematiche e manipolazioni di array.

Operazioni matematiche e manipolazione di array

Le operazioni matematiche in NumPy sono ottimizzate per l’efficienza e la velocità. La libreria supporta tutte le operazioni aritmetiche di base (addizione, sottrazione, moltiplicazione, divisione) sia tra array che tra array e scalari. Queste operazioni sono vettorizzate, il che significa che vengono eseguite elemento per elemento senza la necessità di cicli espliciti.

Le funzioni trigonometriche come sin, cos, tan e le loro inverse sono implementate in modo efficiente e possono essere applicate direttamente agli array. Lo stesso vale per le funzioni esponenziali e logaritmiche. Questa capacità è particolarmente utile nelle applicazioni scientifiche e nell’analisi dei segnali.

La manipolazione di array in NumPy include operazioni come il reshaping (modifica della forma dell’array), lo slicing (selezione di sottoinsiemi di elementi), la concatenazione e la divisione di array. Queste operazioni sono fondamentali per la preparazione dei dati e l’analisi esplorativa.

Esempi di utilizzo delle funzioni di NumPy

Per illustrare l’utilizzo pratico delle funzioni di NumPy, consideriamo alcuni esempi concreti. Supponiamo di dover analizzare un dataset di temperature giornaliere:

 

# Creazione di un array di temperature

temperatures = np.array([20.5, 22.1, 23.4, 21.8, 20.9, 22.5, 23.1])




# Calcolo di statistiche descrittive

media = np.mean(temperatures)

deviazione_standard = np.std(temperatures)

massimo = np.max(temperatures)

minimo = np.min(temperatures)




# Normalizzazione dei dati

temperatures_normalizzate = (temperatures - media) / deviazione_standard




# Applicazione di una funzione trigonometrica

angoli = np.linspace(0, 2*np.pi, 100)

sinusoide = np.sin(angoli)

 

Già da questo semplice esempio possiamo vedere come NumPy possa essere utilizzato per analisi statistiche di base e trasformazioni matematiche più complesse. La capacità di eseguire queste operazioni in modo efficiente su grandi array è uno dei principali vantaggi di NumPy rispetto al Python standard.

 

Un altro aspetto fondamentale di NumPy è la sua capacità di gestire operazioni algebriche avanzate. La libreria fornisce un modulo dedicato, numpy.linalg, che implementa diverse operazioni di algebra lineare essenziali per molte applicazioni scientifiche e di machine learning. Queste includono il calcolo del determinante di una matrice, la risoluzione di sistemi di equazioni lineari, e la decomposizione in valori singolari.

Nel contesto dell’elaborazione dei segnali e dell’analisi delle serie temporali, NumPy offre strumenti potenti per la trasformazione e l’analisi dei dati. La trasformata di Fourier, implementata attraverso il modulo numpy.fft, permette di analizzare i dati nel dominio delle frequenze, una tecnica fondamentale in molti campi dell’ingegneria e della fisica.

Le funzioni di NumPy per la gestione della memoria meritano una menzione speciale. La libreria implementa il concetto di “views” e “copies” degli array, che permette di ottimizzare l’utilizzo della memoria quando si lavora con grandi dataset. Una “view” è essenzialmente un nuovo modo di guardare gli stessi dati in memoria, mentre una “copy” crea una nuova allocazione di memoria con i dati duplicati.

La gestione delle operazioni su array multidimensionali in NumPy è particolarmente sofisticata. Il broadcasting, per esempio, è una caratteristica che permette di eseguire operazioni tra array di forme diverse, seguendo un insieme di regole ben definite. Questo meccanismo semplifica notevolmente il codice e migliora le prestazioni evitando cicli espliciti.

 

# Creazione di un array bidimensionale

matrice = np.array([[1, 2, 3],

                    [4, 5, 6],

                    [7, 8, 9]])




# Creazione di un vettore

vettore = np.array([1, 0, -1])




# Broadcasting: il vettore viene automaticamente "esteso" 

# per corrispondere alla forma della matrice

risultato = matrice + vettore




# Il risultato avrà la stessa forma della matrice

print("Risultato del broadcasting:")

print(risultato)

 

Un’altra caratteristica avanzata di NumPy è la capacità di gestire maschere booleane per la selezione condizionale di elementi. Questo permette di effettuare operazioni complesse su sottoinsiemi di dati in modo efficiente:

 

# Creazione di un array di temperature

temperature = np.array([18.5, 22.1, 25.4, 27.8, 30.9, 32.5, 29.1])




# Creazione di una maschera per temperature superiori a 25°C

maschera_alte = temperature > 25.0




# Selezione delle temperature che soddisfano la condizione

temperature_alte = temperature[maschera_alte]




print("Temperature superiori a 25°C:")

print(temperature_alte)




# Calcolo della media delle temperature alte

media_temperature_alte = np.mean(temperature_alte)

print(f"Media delle temperature alte: {media_temperature_alte:.1f}°C")

 

L’ottimizzazione delle prestazioni è un altro aspetto cruciale di NumPy. La libreria implementa numerose tecniche per massimizzare l’efficienza delle operazioni, come la vettorizzazione e la cache-locality. Questi aspetti tecnici sono particolarmente importanti quando si lavora con dataset di grandi dimensioni o quando si eseguono operazioni computazionalmente intensive.

Nel campo dell’apprendimento automatico, NumPy fornisce le basi per implementare algoritmi fondamentali. Per esempio, l’implementazione di una regressione lineare può essere realizzata in modo efficiente utilizzando le operazioni matriciali di NumPy:

 

# Generazione di dati di esempio

X = np.array([[1, 1], [1, 2], [1, 3], [1, 4], [1, 5]])  # Features con termine costante

y = np.array([2, 4, 5, 4, 5])  # Target




# Calcolo dei coefficienti della regressione utilizzando la formula normale

# β = (X'X)^(-1)X'y

beta = np.linalg.inv(X.T @ X) @ X.T @ y




print("Coefficienti della regressione:")

print(beta)




# Predizione su nuovi dati

X_nuovo = np.array([[1, 6], [1, 7]])

y_pred = X_nuovo @ beta




print("\nPredizioni su nuovi dati:")

print(y_pred)

 

L’integrazione con altre librerie scientifiche è un altro punto di forza di NumPy. La libreria si interfaccia perfettamente con strumenti come Pandas per l’analisi dei dati, Matplotlib per la visualizzazione, e Scikit-learn per il machine learning. Questa interoperabilità ha contribuito a creare un ecosistema Python robusto per il calcolo scientifico.

Conclusione

Per chi si sta avvicinando ai corsi per imparare il machine learning, la padronanza di NumPy è fondamentale. Questa libreria infatti non solo fornisce gli strumenti necessari per manipolare e analizzare i dati, ma aiuta anche a comprendere i concetti matematici sottostanti agli algoritmi di machine learning.

La documentazione di NumPy merita una menzione particolare per la sua completezza e chiarezza. Ogni funzione è accompagnata da spiegazioni dettagliate, esempi pratici e note sulle prestazioni. Questo rende la libreria accessibile anche ai principianti, pur mantenendo la profondità necessaria per gli utenti avanzati.

Lo sviluppo continuo di NumPy è guidato da una comunità attiva di sviluppatori e ricercatori. Le nuove versioni introducono regolarmente ottimizzazioni delle prestazioni e nuove funzionalità, mantenendo al contempo la compatibilità con il codice esistente. Questo impegno per il miglioramento continuo ha contribuito a mantenere NumPy al centro dell’ecosistema Python per il calcolo scientifico.

Insomma, NumPy rappresenta molto più di una semplice libreria per il calcolo numerico in Python. È un ecosistema completo che fornisce gli strumenti necessari per l’analisi dei dati, il calcolo scientifico e il machine learning. La sua efficienza, versatilità e facilità d’uso la rendono una scelta naturale per chiunque lavori con dati numerici in Python. Che si tratti di analisi scientifica, sviluppo di algoritmi di machine learning o elaborazione di segnali, NumPy fornisce le fondamenta necessarie per affrontare queste sfide in modo efficiente ed elegante.

La padronanza di NumPy apre le porte a numerose opportunità nel campo della data science e del machine learning. Per chi desidera approfondire questi argomenti, i corsi specializzati e la vasta documentazione disponibile forniscono un ottimo punto di partenza per sfruttare appieno il potenziale di questa potente libreria.

Simone Truglia

AUTORE:Simone Truglia Apri profilo LinkedIn

Simone è un Ingegnere Informatico con specializzazione nei sistemi automatici e con una grande passione per la matematica, la programmazione e l’intelligenza artificiale. Ha lavorato con diverse aziende europee, aiutandole ad acquisire e ad estrarre il massimo valore dai principali dati a loro disposizione.