Aumentare l’efficienza matematica Navigare nelle operazioni degli array Numpy

Efficienza matematica con array Numpy

 

In questo articolo, scopriremo la potenza di una delle famose e utili librerie Python per l’analisi dei dati, NumPy, in cui la struttura dati primaria per memorizzare gli elementi e eseguire operazioni è un array multidimensionale. Vedremo come questa libreria dinamica rende efficiente il complesso compito matematico riguardo alla complessità spaziale e temporale. Vedremo anche come la manipolazione e la trasformazione dei dati possono essere semplificate grazie a operazioni senza sforzo.

 

Cos’è NumPy?

 

NumPy, Scipy e Matplotlib sono librerie Python utilizzate nei progetti di Data Science, che forniscono funzionalità simili a MATLAB.

   

In particolare, NumPy ha le seguenti caratteristiche:

  1. Array multidimensionali tipizzati (matrici)
  2. Calcoli numerici veloci (matematica matriciale)
  3. Funzioni matematiche di alto livello

NumPy sta per Numerical Python, il pacchetto fondamentale richiesto per il calcolo ad alte prestazioni e l’analisi dei dati. NumPy è necessario per i calcoli numerici in Python perché è progettato per l’efficienza su grandi array di dati.

 

Diverse modalità per creare array NumPy

 

Prima di iniziare a eseguire operazioni sugli array NumPy, il nostro primo obiettivo è diventare competenti nella creazione di un array NumPy in base alle nostre esigenze secondo il problema da risolvere. 

Esistono diversi modi per creare array NumPy. Di seguito sono riportati alcuni metodi standard e pratici:

Caso 1: Utilizzo del metodo np.ones per creare un array di uno:

Se è necessario creare un array di soli “uno”, è possibile utilizzare questo metodo.

np.ones((3,5), dtype=np.float32)
# Output
[[1. 1. 1. 1. 1.]
 [1. 1. 1. 1. 1.]]

 

Caso 2: Utilizzo del metodo np.zeros per creare un array di zeri:

Se è necessario creare un array di soli “zeri”, è possibile utilizzare questo metodo.

np.zeros((6,2), dtype=np.int8)
# Output
[[0 0]
 [0 0]
 [0 0]
 [0 0]
 [0 0]
 [0 0]]

 

Caso 3: Utilizzo del metodo np.arange:

È possibile utilizzare questo metodo se è necessario creare un array di elementi seguendo una sequenza.

np.arange(1334,1338)
# Output
[1334 1335 1336 1337]

 

Caso 4: Utilizzo del metodo np.concatenate:

Questo metodo è appropriato quando l’array richiesto combina uno o più array.

A = np.ones((2,3))
B = np.zeros((4,3))
C = np.concatenate([A, B])
# Output
[[1. 1. 1.]
 [1. 1. 1.]
 [0. 0. 0.]
 [0. 0. 0.]
 [0. 0. 0.]
 [0. 0. 0.]]

 

Caso 5: Utilizzo del metodo np.random.random:

È utile per creare un array con valori casuali.

np.random.random((2,3))
# Output
[[0.30512345 0.10055724 0.89505387]
 [0.36219316 0.593805   0.7643694 ]]

 

Operazioni sugli array NumPy

 

Discutiamo le proprietà di base di un array NumPy con un esempio:

Codice:

a = numpy.array([[1,2,3],[4,5,6]],dtype=numpy.float32)
# Dimensioni dell'array, forma e tipo di dati
print (a.ndim, a.shape, a.dtype)
Output:
2 (2, 3) float32

 

Basandoci sul codice sopra, abbiamo i seguenti punti da ricordare come conclusione:

  1. Gli array possono avere qualsiasi dimensione come numero intero positivo, incluso zero (corrisponde a un valore scalare).
  2. Gli array hanno un tipo e possono avere tipi di dati come np.uint8, np.int64, np.float32, np.float64
  3. Gli array sono densi. Ogni elemento dell’array esiste ed ha lo stesso tipo.

Codice:

# Reshape degli array
a = numpy.array([1,2,3,4,5,6])
a = a.reshape(3,2)              
#Output: 
[[1 2]                 
[3 4]                           
[5 6]]

a = a.reshape(2,-1)
#Output: 
[[1 2 3]
 [4 5 6]]

a = a.ravel()
#Output:  
[1 2 3 4 5 6]

 

Punti importanti da ricordare:

  1. Il numero totale di elementi nell’array non può cambiare dopo l’operazione di reshape.
  2. Per inferire la forma dell’asse, utilizzare -1.
  3. Per impostazione predefinita, memorizza l’elemento nel formato Row-major, mentre d’altra parte, in MATLAB, è column-major.

 

Broadcasting degli Array Numpy

 

Il broadcasting consente di eseguire operazioni su array di forme diverse purché siano compatibili. Le dimensioni più piccole di un array vengono virtualmente espandate per corrispondere alle dimensioni dell’array più grande.

   

Codice:

# Broadcasting degli array
a = numpy.array([[1, 2], [3, 4], [5, 6]])
b = numpy.array([10, 20])
c = a + b  # Broadcasting dell'array 'b' per corrispondere alle dimensioni di 'a'

 

L’esempio coinvolge un array NumPy 2D ‘a’ con dimensioni (3, 2) e un array 1D ‘b’ con forma (2). Il broadcasting consente all’operazione ‘a + b’ di espandere virtualmente ‘b’ per corrispondere a ‘a’ nella seconda dimensione, risultando in una somma elemento per elemento tra ‘a’ e ‘b’ espanso.

 

Indicizzazione e Slicing degli Array

 

  1. Gli slice sono viste. Scrivendo su uno slice si sovrascrive l’array originale.
  2. Una lista o un array booleano può anche indicizzarlo.
  3. Sintassi di indicizzazione in Python:

start_index : stop_index: step_size

Codice:

a = list(range(10)) 

 # primi 3 elementi
a[:3] # indici 0, 1, 2 

# ultimi 3 elementi
a[-3:] # indici 7, 8, 9 

# indici 3, 5, 7 
a[3:8:2] 

# indici 4, 3, 2 (questo è un po' complicato)
a[4:1:-1] 

 

Come sai, un’immagine può essere visualizzata anche come un array multidimensionale. Quindi, lo slicing può essere utile anche per eseguire alcune operazioni matematiche sulle immagini. Alcuni esempi importanti e avanzati sono menzionati di seguito per aumentare la comprensione:

# Seleziona tutto tranne il bordo di un pixel 
pixel_matrix[1:-1,1:-1]         

# Scambia l'ordine dei canali 
pixel_matrix = pixel_matrix[:,:,::-1]

# Imposta i pixel scuri a nero  
pixel_matrix[pixel_matrix<10] = 0

# Seleziona la seconda e la quarta riga        
pixel_matrix[[1,3], :]  

 

Aggregazione e Riduzione degli Array

 

Ora, inizieremo con le operazioni di aggregazione sugli array numpy. In generale, le operazioni che è possibile eseguire sono le seguenti:

  1. Trovare la somma e il prodotto di tutti gli elementi dell’array.
  2. Trovare l’elemento massimo e minimo nell’array
  3. Trovare il conteggio di un elemento particolare in un array
  4. Possiamo anche trovare altri parametri utilizzando il modulo di algebra lineare, tra cui determinante della matrice, traccia della matrice, autovalori e autovettori della matrice, ecc.

Iniziamo a discutere di ogni funzionalità con degli esempi:

Caso-1: Somma algebrica di tutti gli elementi presenti nell’array

array_1 = numpy.array([[1,2,3], [4,5,6]])
print(array_1.sum())
#Output: 
21

 

Caso-2: Elemento massimo nell’array

array_1 = numpy.array([[1,2,3], [4,5,6]])
print(array_1.max())
#Output: 
6

 

Caso-3: Elemento minimo nell’array

array_1 = numpy.array([[1,2,3], [4,5,6]])
print(array_1.min())
#Output: 
1

 

Caso-4: Posizione/Indice dell’elemento nell’array in cui si trova l’elemento massimo

array_1 = numpy.array([[1,2,3], [4,5,6]])
print(array_1.argmax())
#Output: 
5

 

Caso-5: Posizione/Indice dell’elemento nell’array in cui si trova l’elemento minimo

array_1 = numpy.array([[1,2,3], [4,5,6]])
print(array_1.argmin())
#Output: 
0

 

Mentre si trova la posizione, si può osservare che considera ogni array multidimensionale come un array 1-D e poi lo calcola.

Caso-6: Media di tutti gli elementi in un array

array_1 = numpy.array([[1,2,3], [4,5,6]])
print(array_1.mean())
#Output: 
3.5

 

Caso-7: Prodotto scalare di due array multidimensionali

array_1 = numpy.array([[1,2], [4,5]])
array_2 = numpy.array([[1,-1,2], [3,7,-2]])
t = array_1.dot(array_2)
print(t)
#Output: 
[[ 7 13 -2]
 [19 31 -2]]

 

Vettorizzazione negli array Numpy

 

La vettorizzazione consente di eseguire operazioni su interi array anziché attraverso singoli elementi. Sfrutta routine ottimizzate a basso livello, garantendo codice più veloce e conciso.

Codice:

a = numpy.array([1, 2, 3, 4, 5])
b = numpy.array([10, 20, 30, 40, 50])
c = a + b  # Somma elemento per elemento senza cicli espliciti

 

Sulla base dell’esempio precedente, si può vedere che vengono creati due array NumPy, chiamati ‘a’ e ‘b’. Nell’operazione ‘a + b’, in cui viene eseguita una somma elemento per elemento tra gli array utilizzando il concetto di vettorizzazione, viene creato un nuovo array ‘c’ contenente la somma degli elementi corrispondenti di ‘a’ e ‘b’. Pertanto, a causa dell’operazione elemento per elemento, il programma evita di eseguire cicli espliciti e utilizza routine ottimizzate per un calcolo efficiente.

 

Concatenazione di array

 

Caso-1: Supponiamo che tu abbia due o più array da concatenare utilizzando la funzione concatenate, in cui devi unire la tupla degli array.

Codice:

# concatenate 2 o più array utilizzando la funzione concatenate per righe
numpy_array_1 = numpy.array([1,2,3])
numpy_array_2 = numpy.array([4,5,6])
numpy_array_3 = numpy.array([7,8,9])
array_concatenate = numpy.concatenate((numpy_array_1, numpy_array_2, numpy_array_3))
print(array_concatenate)
#Output:
[1 2 3 4 5 6 7 8 9]

 

Caso 2: Supponiamo che tu abbia un array con più di una dimensione; quindi, per concatenare gli array, devi specificare l’asse lungo cui devono essere concatenati. Altrimenti, verrà eseguito lungo la prima dimensione. 

Codice:

# concatenare 2 o più array utilizzando la funzione concatenate colonna per colonna
array_1 = numpy.array([[1,2,3], [4,5,6]])
array_2 = numpy.array([[7,8,9], [10, 11, 12]])
array_concatenate = numpy.concatenate((array_1, array_2), axis=1)
print(array_concatenate)
#Output:
[[ 1  2  3  7  8  9]
 [ 4  5  6 10 11 12]]

 

Funzioni Matematiche e Funzioni Universali

 

Queste funzioni universali sono anche conosciute come ufuncs. In queste funzioni vengono eseguite operazioni elemento per elemento. Per esempio:

  1. np.exp
  2. np.sqrt
  3. np.sin
  4. np.cos
  5. np.isnan

Codice:

A = np.array([1,4,9,16,25])
B = np.sqrt(A)
#Output
[1. 2. 3. 4. 5.]

 

Confronti di Prestazioni

 

Nel caso di calcoli numerici, Python richiede molto tempo se abbiamo calcoli complessi. Se prendiamo una matrice di dimensioni 1000 x 1000 e ne eseguiamo la moltiplicazione, il tempo richiesto da Python e numpy sarà:

  1. Il triplo loop di Python richiede > 10 minuti
  2. Numpy richiede ~0.03 secondi

Quindi, dall’esempio sopra, possiamo vedere che numpy richiede significativamente meno tempo rispetto a Python standard, quindi la nostra latenza si riduce nei progetti di Data Science in cui si devono elaborare grandi quantità di dati.

 

Conclusione

 

In questo articolo abbiamo discusso gli array di numpy. Quindi, per concludere la nostra sessione, riassumiamo i vantaggi di numpy rispetto a Python:

  1. Numpy ha una computazione orientata agli array.
  2. Numpy ha implementato efficientemente array multidimensionali.
  3. Numpy è principalmente progettato per il calcolo scientifico.
  4. Numpy contiene funzioni matematiche standard per un calcolo più veloce sugli array senza cicli.
  5. Numpy ha un’implementazione incorporata dell’algebra lineare e della generazione di numeri casuali per lavorare con capabilities di trasformata di Fourier.
  6. Numpy contiene anche strumenti per la lettura e la scrittura di array su disco e per lavorare con file a mappa di memoria.

    Aryan Garg è uno studente di Ingegneria Elettrica al terzo anno del suo corso di laurea. Il suo interesse si concentra nel campo dello sviluppo web e dell’apprendimento automatico. Ha seguito questo interesse ed è desideroso di lavorare ulteriormente in queste direzioni.