Sto cercando soluzioni per accelerare una funzione che ho scritto per scorrere un dataframe panda e confrontare i valori delle colonne tra la riga corrente e la riga precedente .Il modo più veloce per confrontare riga e riga precedente in dataframe panda con milioni di righe
Ad esempio, questa è una versione semplificata del mio problema:
User Time Col1 newcol1 newcol2 newcol3 newcol4
0 1 6 [cat, dog, goat] 0 0 0 0
1 1 6 [cat, sheep] 0 0 0 0
2 1 12 [sheep, goat] 0 0 0 0
3 2 3 [cat, lion] 0 0 0 0
4 2 5 [fish, goat, lemur] 0 0 0 0
5 3 9 [cat, dog] 0 0 0 0
6 4 4 [dog, goat] 0 0 0 0
7 4 11 [cat] 0 0 0 0
Al momento ho una funzione che scorre e calcola i valori per 'newcol1
' e 'newcol2
' a seconda che il ' User
'è cambiato rispetto alla riga precedente e anche se la differenza nei valori' Time
'è maggiore di 1. Guarda anche il primo valore negli array memorizzati in' Col1
'e' Col2
'e gli aggiornamenti' newcol3
'e' newcol4
'se questi valori sono cambiati rispetto alla riga precedente.
Ecco la pseudo-codice per quello che sto facendo attualmente (da quando ho semplificato il problema non ho ancora testato questo, ma è abbastanza simile a quello che sto realmente facendo in notebook ipython):
def myJFunc(df):
... #initialize jnum counter
... jnum = 0;
... #loop through each row of dataframe (not including the first/zeroeth)
... for i in range(1,len(df)):
... #has user changed?
... if df.User.loc[i] == df.User.loc[i-1]:
... #has time increased by more than 1 (hour)?
... if abs(df.Time.loc[i]-df.Time.loc[i-1])>1:
... #update new columns
... df['newcol2'].loc[i-1] = 1;
... df['newcol1'].loc[i] = 1;
... #increase jnum
... jnum += 1;
... #has content changed?
... if df.Col1.loc[i][0] != df.Col1.loc[i-1][0]:
... #record this change
... df['newcol4'].loc[i-1] = [df.Col1.loc[i-1][0], df.Col2.loc[i][0]];
... #different user?
... elif df.User.loc[i] != df.User.loc[i-1]:
... #update new columns
... df['newcol1'].loc[i] = 1;
... df['newcol2'].loc[i-1] = 1;
... #store jnum elsewhere (code not included here) and reset jnum
... jnum = 1;
Ora ho bisogno di applicare questa funzione a diversi milioni di righe ed è incredibilmente lento, quindi sto cercando di capire il modo migliore per accelerarlo. Ho sentito che Cython può aumentare la velocità delle funzioni, ma non ne ho esperienza (e sono nuovo sia per i panda che per i python). È possibile passare due righe di un dataframe come argomenti alla funzione e quindi usare Cython per velocizzarlo o sarebbe necessario creare nuove colonne con valori "diff
" in modo che la funzione legga e scriva solo in una riga del dataframe alla volta, per trarre beneficio dall'uso di Cython? Qualsiasi altro trucchetto di velocità sarebbe molto apprezzato!
(Per quanto riguarda usando .loc, ho confrontato .loc, .iloc e .ix e questo era leggermente più veloce in modo che è l'unico motivo che sto utilizzando attualmente)
(Inoltre, il mio User
colonna la realtà è unicode non int, che potrebbe essere problematica per raffronti rapidi)
Con un milione di righe, perché non utilizzare un database dedicato che Python può facilmente connettersi a MySQL o SQLlite? I database relazionali possono eseguire query SQL complesse con logica if/then per il confronto riga a riga unito da indici. Sono progettati per scalare per milioni di file. Anche un trigger può essere impostato in modo che, con qualsiasi modifica dell'utente, le colonne specifiche possano essere aggiornate. – Parfait