Ho una configurazione semplice: dati di mercato (zecche) in un dataframe df panda in questo modo:accelerare le funzioni di aggregazione personalizzate
index period ask bid
00:00:00.126 42125 112.118 112.117
00:00:00.228 42125 112.120 112.117
00:00:00.329 42125 112.121 112.120
00:00:00.380 42125 112.123 112.120
00:00:00.432 42125 112.124 112.121
00:00:00.535 41126 112.124 112.121
00:00:00.586 41126 112.122 112.121
00:00:00.687 41126 112.124 112.121
00:00:01.198 41126 112.124 112.120
00:00:01.737 41126 112.124 112.121
00:00:02.243 41126 112.123 112.121
Ora uso pandas.groupy a periodi aggregati
g=df.groupby('period')
È facile ottenere prezzi minimi e massimi per periodo, ad es
import numpy as np
res=g.agg({'ask': [np.amax, np.amin]})
Anche questo è abbastanza veloce. Ora, voglio anche il primo e l'ultimo prezzo per periodo. Questo è dove iniziano i problemi. Naturalmente, non posso fare:
res=g.agg({'ask': lambda x: x[0]})
e funziona, in pratica, ma è terribilmente lento per grandi insiemi di dati. Fondamentalmente, l'overhead di chiamata per una chiamata di funzione Python è semplicemente enorme.
Qualcuno sa di una funzione numpy analoga a np.amax che restituirà il primo o l'ultimo elemento di un gruppo? Non sono riuscito a trovarne uno. iloc [0] non fa il trucco perché è un metodo di un oggetto e, quindi, non posso passarlo come una funzione a g.agg, perché non ho l'oggetto in questa fase (questo è ciò che il lambda è necessario per).
Ora, non sono pigro e ho provato a farlo da solo utilizzando cython.
import numpy as np
cimport numpy as np
cpdef double first(np.ndarray array_series):
return array_series[0]
Ma panda non accettare questo come una funzione di aggregazione perché passa un pd.core.series-oggetto piuttosto che un np.ndarray. (Neppure uno deriva dall'altra, il compilatore non lo riconosce)
Qualcuno sa come scrivere una funzione cython che accetta una serie di panda senza il sovraccarico di chiamata Python?
Hai provato 'df.groupby ('periodo') prima.() 'e' df.groupby ('periodo'). last() '? – EdChum
Grazie, è un buon suggerimento. Funziona, ma non posso passare la funzione first() - g.agg (...), posso? Mi piacerebbe di più, perché vorrei applicare molte funzioni di aggregazione diverse contemporaneamente (amin, amax, first, ...). Sarà una soluzione temporanea per usarlo e quindi assemblare manualmente il mio set di dati finale, suppongo. – user5507059
Sì, puoi, per favore vedi la mia risposta – EdChum