2016-03-16 9 views
6

Ich habe einen sehr großen Pandas-Datensatz, und irgendwann muß ich die folgende FunktionWie beschleunigt man eine sehr langsame Pandas-Apply-Funktion?

def proc_trader(data): 
    data['_seq'] = np.nan 
    # make every ending of a roundtrip with its index 
    data.ix[data.cumq == 0,'tag'] = np.arange(1, (data.cumq == 0).sum() + 1) 
    # backfill the roundtrip index until previous roundtrip; 
    # then fill the rest with 0s (roundtrip incomplete for most recent trades) 
    data['_seq'] =data['tag'].fillna(method = 'bfill').fillna(0) 
    return data['_seq'] 
    # btw, why on earth this function returns a dataframe instead of the series `data['_seq']`?? 

und ich

Offensichtlich
reshaped['_spell']=reshaped.groupby(['trader','stock'])[['cumq']].apply(proc_trader) 

anwenden verwenden verwenden, kann ich die Daten hier nicht teilen, aber tue Sie sehen einen Engpass in meinem Code? Könnte es die arange Sache sein? Es gibt viele name-productid Kombinationen in den Daten.

Minimal Arbeitsbeispiel:

import pandas as pd 
import numpy as np 

reshaped= pd.DataFrame({'trader' : ['a','a','a','a','a','a','a'],'stock' : ['a','a','a','a','a','a','b'], 'day' :[0,1,2,4,5,10,1],'delta':[10,-10,15,-10,-5,5,0] ,'out': [1,1,2,2,2,0,1]}) 


reshaped.sort_values(by=['trader', 'stock','day'], inplace=True) 
reshaped['cumq']=reshaped.groupby(['trader', 'stock']).delta.transform('cumsum') 
reshaped['_spell']=reshaped.groupby(['trader','stock'])[['cumq']].apply(proc_trader).reset_index()['_seq'] 
+1

haben Sie versucht, Line-Profilieren der Code? – EnricoGiampieri

+0

Ich habe keine Ahnung, wie man das macht –

+1

gibt es eine Bibliothek dafür, und arbeiten wunderbar, überprüfen Sie es! Ich würde es mir ansehen, aber es ist wahrscheinlich datenabhängig. https://github.com/rkern/line_profiler – EnricoGiampieri

Antwort

0

Nichts wirklich hier Besonderes, nur in ein paar Plätze gezwickt. Es gibt wirklich keine Notwendigkeit, eine Funktion zu setzen, also tat ich nicht. Auf diesen winzigen Beispieldaten ist es etwa doppelt so schnell wie das Original.

reshaped.sort_values(by=['trader', 'stock','day'], inplace=True) 
reshaped['cumq']=reshaped.groupby(['trader', 'stock']).delta.cumsum() 
reshaped.loc[ reshaped.cumq == 0, '_spell' ] = 1 
reshaped['_spell'] = reshaped.groupby(['trader','stock'])['_spell'].cumsum() 
reshaped['_spell'] = reshaped.groupby(['trader','stock'])['_spell'].bfill().fillna(0) 

Ergebnis:

day delta out stock trader cumq _spell 
0 0  10 1  a  a 10  1.0 
1 1 -10 1  a  a  0  1.0 
2 2  15 2  a  a 15  2.0 
3 4 -10 2  a  a  5  2.0 
4 5  -5 2  a  a  0  2.0 
5 10  5 0  a  a  5  0.0 
6 1  0 1  b  a  0  1.0