Vettorizzazione e trasmissione in Python
Pubblicato: 2020-12-01La vettorizzazione e la trasmissione sono modi per accelerare il tempo di calcolo e ottimizzare l'utilizzo della memoria mentre si eseguono operazioni matematiche con Numpy. Questi metodi sono fondamentali per garantire che la complessità del tempo sia ridotta in modo che gli algoritmi non debbano affrontare colli di bottiglia. Questa operazione ottimizzata è necessaria affinché le applicazioni siano scalabili. Esamineremo entrambe queste tecniche e implementeremo alcuni esempi.
Alla fine di questo tutorial, avrai la conoscenza di quanto segue:
- Come la vettorizzazione viene gestita da Numpy
- Differenze di tempo con e senza vettorizzazione
- Che cos'è la trasmissione
- Come Broadcasting è diverso dalla solita moltiplicazione Matrix
Vettorizzazione
Molte volte abbiamo bisogno di operazioni matematiche sugli array, come la moltiplicazione di array. Ora, un modo non vettorizzato sarebbe quello di eseguire la moltiplicazione degli elementi utilizzando un ciclo. Implementarlo in questo modo comporterebbe l'esecuzione della stessa operazione di moltiplicazione più volte, il che sarebbe uno spreco di risorse di calcolo se la dimensione dei dati è troppo grande. Diamo una rapida occhiata.
Modo non vettorizzato:
Importa casuale a = [random.randint( 1 , 100 ) for _ in range( 10000 )] |
#Produzione: >> 1000 loop, al meglio di 3 : 658 µs per loop |
Modo vettorizzato:
importa numpy come np a = np.array([random.randint( 1 , 100 ) for _ in range( 10000 )]) b = np.array([random.randint( 1 , 100 ) for _ in range( 10000 )]) %timeit a*b |
#Produzione: >> 100000 loop, al meglio di 3 : 7,25 µs per loop |
Come si vede, il tempo trascorso è passato da 658 microsecondi a soli 7,25 microsecondi. Questo perché quando diciamo a = np.array([]) , tutte le operazioni vengono gestite internamente da numpy. E quando facciamo a*b , numpy internamente moltiplica l'array completo in una volta per mezzo della vettorizzazione.
Qui usiamo il comando %timeit magic per cronometrare l'esecuzione del processo che potrebbe differire sulla tua macchina.
Diamo un'occhiata a un altro esempio di prodotti esterni di 2 vettori con dimensioni (nx1) e (1xm). L'output sarà (nxm).
tempo di importazione importare numpy matrice di importazione a = array.array( 'i' , [random.randint( 1 , 100 ) for _ in range( 100 )]) b = array.array( 'i' , [random.randint( 1 , 100 ) for _ in range( 100 )]) |
T1 = tempo.tempo_processo() c = numpy.zeros(( 200 , 200 )) for i in range(len(a)): per j nell'intervallo (len(b)): c[i][j]= a[i]*b[j] T2 = tempo.tempo_processo() print( f”Tempo di calcolo = { 1000 *(T2-T1)} ms” ) |
#Produzione: >> Tempo di calcolo = 6,819299000000001 ms |
Ora, facciamolo con Numpy,
T1 = tempo.tempo_processo() c = numpy.outer(a, b) T2 = tempo.tempo_processo() print( f”Tempo di calcolo = { 1000 *(T2-T1)} ms” ) |
#Produzione: >> Tempo di calcolo = 0,2256630000001536 ms |
Come vediamo di nuovo, Numpy elabora la stessa operazione molto più velocemente tramite la vettorizzazione.
Da leggere: affascinanti applicazioni Python nel mondo reale
Quindi fino ad ora, abbiamo visto esempi in cui sono stati utilizzati array della stessa dimensione. Cosa succede se le dimensioni degli array sono diverse? È qui che entra in gioco un'altra grande funzionalità di Numpy, Broadcasting.
La trasmissione è un'altra estensione della vettorizzazione in cui gli array non devono avere le stesse dimensioni per eseguire operazioni su di essi come addizione, sottrazione, moltiplicazione, ecc. Capiamolo con un esempio molto semplice di addizione di un array e uno scalare.
a = np.array([ 1 , 1 , 1 , 1 ]) a+ 5 |
#Produzione: matrice([ 6 , 6 , 6 , 6 ]) |
Come vediamo, lo scalare 5 è stato aggiunto a tutti gli elementi. Allora come è successo?

Per immaginare il processo, si può pensare che lo scalare 5 venga ripetuto 4 volte per creare un array che viene poi aggiunto all'array a. Ma tieni presente che Numpy non crea tali array che occuperanno solo memoria. Numpy semplicemente "trasmette" o duplica lo scalare da 5 a 4 posti per aggiungerlo all'array a.
Facciamo un altro semplice esempio.
a = np.ones(( 3 , 3 )) b = np.ones( 3 ) a+b |
#Produzione: >> array([[ 2. , 2. , 2. ], [ 2. , 2. , 2. ], [ 2. , 2. , 2. ]]) |
Nell'esempio sopra, l'array di forma (3,1) è stato trasmesso a (3,3) in modo che corrisponda all'array a.
Ma questo significa che qualsiasi array con qualsiasi dimensione può essere trasmesso per abbinare un array con qualsiasi dimensione?
NO!
Regole di trasmissione
Numpy segue una serie di semplici regole per assicurarsi che vengano trasmessi solo gli array che seguono i criteri. Diamo un'occhiata.
La regola della trasmissione dice che i 2 array che devono essere utilizzati devono avere le stesse dimensioni o se uno di loro è 1.
Vediamo che è in azione.
Esempio 1:
Considera di seguito gli array di dimensioni:
a = 3 x 4 x 7
b = 3 x 4 x 1
Qui l'ultima dimensione di b verrà trasmessa in modo che corrisponda a quella da a a 7.
Quindi, risultato = 3 x 4 x 7
Esempio 2:
a = 3 x 4 x 7
b = 4
Ora, il numero di dimensioni di aeb sono disuguali. In questi casi l'array con un numero di dimensioni inferiore verrà riempito con 1.
Quindi, qui, la prima e l'ultima dimensione di b sono 1, quindi verranno trasmesse in modo che corrispondano a quelle di a a 3 e 7.
Quindi, risultato = 3 x 4 x 7.
Leggi: Tutorial Python
Esempio 3:
a = 3 x 4 x 1 x 5
b = 3 x 1 x 7 x 1
Anche in questo caso, la seconda e l'ultima dimensione di b verranno trasmesse in modo che corrispondano a quelle da a a 4 e 5. Inoltre, la terza dimensione di a verrà trasmessa in modo che corrisponda a quella di b a 7.
Quindi, risultato = 3 x 4 x 7 x 5
Ora vediamo quando la condizione fallisce:
Esempio 4:
a = 3 x 4 x 7 x 5
b = 3 x 3 x 7 x 4
Qui, la seconda e la quarta dimensione di b non corrispondono a a e nemmeno 1. In questo caso, Python genererà un errore di valore:
ValueError: impossibile trasmettere gli operandi insieme alle forme ( 3 , 4 , 7 , 5 ) ( 3 , 3 , 7 , 4 ) |
Esempio 5:
a = 3 x 4 x 1 x 5
b = 3 x 2 x 3
Risultato: ValueError
Anche qui, la seconda dimensione non corrisponde e non è nemmeno 1 per nessuna delle due.
Prima che tu vada
Vettorizzazione e Broadcasting, entrambi, sono metodi con cui Numpy rende la sua elaborazione ottimizzata e più efficiente. Questi concetti dovrebbero essere tenuti a mente soprattutto quando si ha a che fare con matrici e array n-dimensionali, che sono molto comuni nei dati di immagine e nelle reti neurali.
Se sei curioso di conoscere Python, la scienza dei dati, dai un'occhiata al Diploma PG in Data Science di IIIT-B e upGrad, creato per i professionisti che lavorano e offre oltre 10 casi di studio e progetti, workshop pratici pratici, tutoraggio con esperti del settore, 1 contro 1 con mentori del settore, oltre 400 ore di apprendimento e assistenza al lavoro con le migliori aziende.
Che cos'è la vettorizzazione in Python?
Numpy è un pacchetto Python che fornisce diverse funzioni matematiche standard che consentono operazioni rapide su grandi array di dati senza la necessità di loop, inclusa la vettorizzazione. La vettorizzazione viene utilizzata per accelerare i programmi Python senza l'uso di loop. L'uso di un tale metodo può aiutare a ridurre la quantità di tempo necessaria per l'esecuzione del codice. Esistono varie operazioni che vengono eseguite sui vettori, come il prodotto scalare dei vettori, noto anche come prodotto scalare perché produce un unico output, prodotti esterni, che risulta in una matrice quadrata di dimensione uguale alla lunghezza x lunghezza del vettori, moltiplicazione per elemento, che produce elementi con gli stessi indici.
Che cos'è la trasmissione in Python?
La parola broadcasting si riferisce al modo in cui Numpy gestisce array con dimensioni diverse durante operazioni aritmetiche che comportano restrizioni specifiche; l'array più piccolo viene trasmesso attraverso l'enorme array in modo che le loro forme siano coerenti. La trasmissione consente di vettorizzare le operazioni di array in modo tale che il loop avvenga in C anziché in Python, come fa Numpy. Lo fa senza creare copie non necessarie dei dati, con conseguenti implementazioni di algoritmi efficienti. In determinate situazioni, la trasmissione è un'idea negativa poiché si traduce in uno spreco di memoria, che rallenta l'elaborazione.
Quali sono gli usi di NumPy in Python?
NumPy o Numerical Python è una libreria Python gratuita e open source utilizzata da quasi tutti i rami della ricerca e dell'ingegneria. La libreria NumPy include strutture di dati di matrice e matrice multidimensionale e offre metodi per operare in modo efficiente su un array, un oggetto array n-dimensionale omogeneo. Gli utenti possono utilizzare NumPy per eseguire un'ampia gamma di operazioni matematiche sugli array. Migliora Python con solide strutture di dati che forniscono calcoli efficienti con array e matrici, nonché un'enorme libreria di funzioni matematiche di alto livello che funzionano su questi array e matrici.