oltre all'uso di Numpy / Scipy / Pandas, come posso vectorizzare il codice in python

-2

Mi piacerebbe vettorizzare alcune operazioni su array che non sono effettivamente disponibili in ndarray o pandas dataframes / series, come ad esempio confrontare due array / serie / frame di una forma simile, uno di questi contenente un valore e l'altro uno una lista. Posso scrivere la mia struttura dati in Python che usa la vettorizzazione? Come posso chiamare metodi dalla libreria generale che vettorializzare, o usare le funzioni fondamentali per fare questo? Non c'è modo di vectorize in Python senza fare affidamento su Fortran / C quindi su SciPy / NumPy / Pandas e simili librairie? Non capisco perché Python da solo non sarebbe in grado di gestire array come C, in realtà? È "impossibile per concezione" o semplicemente non è fatto perché gli offload sono migliori?

Ad esempio, la vettorizzazione viene eseguita quando si aggiungono due array in numpy come ndarray_1 ([1,2,3]) e ndarray_2 ([3,2,6]) che daranno ndarray_3 ([4,4,9] ) in un solo passaggio, e non c'è un loop invisibile, in realtà tutte le operazioni avvengono in un unico passaggio in memoria. Mi piacerebbe sapere in che misura il codice funziona in modo così vettoriale in python (senza usare numpy, per la mia illuminazione).

Analogamente a quanto descritto sopra, sarebbe particolarmente utile per me sapere che come so ci sono funzioni che sfruttano le proprietà delle parole speciali è e in, come isin in panda, che confrontano un'intera serie per vedere se i singoli elementi sono contenuti nell'iteratore fornito. Purtroppo, se ho un array di liste, devo usare un loop per passare sopra questo array per fornire in sequenza l'iteratore da confrontare in "isin". Questo non va bene per la mia applicazione.

Altri casi d'uso eliminerebbero funzioni come la mappa e l'applicazione, che sono mascherate da cicli con ottimizzazioni, per andare verso la vera vettorizzazione. Come applicare in un round su una serie o frame, element wise, il test del tipo di istanza (isinstance), funziona in base a una formula matematica ma anche a una condizione (anche se, qui, potrei eseguire la matematica f (x) vettoriale quindi in un altro passaggio applica la formula booleana), e così via. Ci sono un sacco di casi d'uso, anzi so che posso fare un po 'con Numpy / Pandas.

Ma, in primo luogo, non posso fare tutto ciò che voglio fare (come trovare se un elemento di un frame è in una lista di un frame comparabile, in base agli elementi, come detto sopra, che sarebbe tremendamente utile ), e mi obbliga a frenare il codice steampunk (che funziona con una strana trasformazione della scienza conosciuta, ma potrebbe non farlo se lo guardi da vicino e con scetticità, e che comunque è brutto e contorto) per farla franca. Inoltre, queste soluzioni non sono sempre efficienti e, quando lo sono, sono solo moderatamente.

In secondo luogo, voglio imparare a diventare un programmatore migliore. Ciò significa non solo affidarsi al lavoro svolto in precedenza senza comprenderlo, o affidarsi a hack o derivati come spingere tutto in cython, numba, C e Fortran sotto il cofano. Se i veri approcci vettorizzati sono fattibili in python, anche se meno performanti a causa delle specificità del linguaggio (comunque, sappiamo tutti che in fondo, qualsiasi cosa qui è più lento di C, C ++ e Fortran a parte forse alcuni nuovi linguaggi che non sono interpretati ma compilato), mi piacerebbe imparare a sapere come, come parte del miglioramento delle mie capacità e comprensione della programmazione.

Di qui la mia domanda. Grazie per avermi aiutato a farlo meglio.

    
posta Ando Jurai 13.12.2017 - 18:12
fonte

1 risposta

1

Odio davvero scoppiare la tua bolla dopo la nostra lunga discussione nei commenti, ma la tua richiesta:

vectorization is performed when adding two arrays in numpy such as ndarray_1([1,2,3]) and ndarray_2([3,2,6]) which will give ndarray_3([4,4,9]) in one step, and there is no invisible loop, actually all the operations happens in one step in memory.

In realtà non è affatto così, esiste effettivamente un "ciclo nascosto" in TUTTI i linguaggi basati su array, (che hai collegato a qui ), e in effetti deve esserci perché anche la maggior parte dei nuovi processi ha 8 o meno thread disponibili e quindi nella migliore istanza non è possibile aggiungere più di 8 elementi di un array alla volta (si veda questa domanda di stackoverflow).

Potresti aver sentito parlare molto dell'elaborazione su GPU, e questo è esplicitamente per questo motivo esatto. Una GPU può elaborare un intero grande vettore in una volta sola, poiché le GPU avranno in genere migliaia di core ciascuno con un massimo di dieci thread, consentendo le aggiunte vettoriali a passaggio singolo per i vettori con decine di migliaia di elementi. Anche le GPU, tuttavia, dovranno suddividere un'attività abbastanza grande in blocchi, che è effettivamente un ciclo for.

Le librerie di terze parti come numba possono aiutarti a eseguire codice python nativo (e codice numpy!) su una GPU per ottenere il parallelismo vuoi.

Si noti che anche con il vantaggio dell'elaborazione parallela, ci sono overheads coinvolti nello spostamento dei numeri dalla CPU alla memoria della GPU, così che per attività più piccole, un ciclo for semplice sarà ancora più veloce.

    
risposta data 14.12.2017 - 12:26
fonte

Leggi altre domande sui tag