2 votes

Python Pandas - groupby() avec apply() & rolling() très lent

Tout d'abord, je suis assez novice en matière de Python et de Pandas, alors soyez patient et répondez en des termes aussi simples que possible. De plus, si vous pouviez développer tout code qui est différent de ce que j'ai dans mon exemple ou m'indiquer une référence solide qui faciliterait la compréhension, je vous en serais très reconnaissant.

J'ai un dataframe (df1) de données mensuelles avec 60+ colonnes et 800k lignes (et en croissance) pour 6000+ sites. J'essaie de calculer la moyenne mobile (3 mois, 12 mois, YTD, etc.) en me basant sur le numéro de licence de l'établissement. ("lic_num", int) , mois ('mo_yr', date) . J'ai réussi à le faire en utilisant apply(). Le problème est que apply() est très lent et prend 10 minutes. Ce n'est pas un problème majeur pour ce projet car ce ne sera pas quelque chose qui devra être exécuté à la demande, mais je veux devenir plus efficace dans l'écriture de code similaire à celui-ci dans le cas où j'ai besoin qu'un projet s'exécute plus rapidement. Voici un exemple de dataframe (df1) et le code que j'utilise pour obtenir mes résultats

lic_num      mo_yr        ap         aw       fi
120700142 2013-03-01  228214.3  206273.53  61393.0
120700142 2013-04-01  256239.4  235296.96  64228.0
120700142 2013-05-01  247725.3  227165.09  74978.0
120700142 2013-06-01  229776.8  211765.55  64559.0
120700142 2013-07-01  229036.2  210963.06  58132.0

df1_col_list = df1.columns.tolist()

for col in df1_col_list[2:5]:
    df1[col+'_3mo'] = df1.groupby('lic_num', as_index=False).apply(
    lambda x: x.rolling(3, on='mo_yr', min_periods=1)[col].mean()).reset_index(level=0, drop=True)

lic_num      mo_yr        ap         aw       fi         ap_3mo         aw_3mo        fi_3mo
120700142 2013-03-01  228214.3  206273.53  61393.0  228214.300000  206273.530000  61393.000000
120700142 2013-04-01  256239.4  235296.96  64228.0  242226.850000  220785.245000  62810.500000
120700142 2013-05-01  247725.3  227165.09  74978.0  244059.666667  222911.860000  66866.333333
120700142 2013-06-01  229776.8  211765.55  64559.0  244580.500000  224742.533333  67921.666667
120700142 2013-07-01  229036.2  210963.06  58132.0  235512.766667  216631.233333  65889.666667

4voto

W-B Points 94428

Si apply est lent, nous essayons de ne pas l'utiliser. Voici plus d'informations sur les raisons de cette lenteur apply est lent Quand devrais-je utiliser pandas apply() dans mon code ?

s=df.groupby('lic_num', as_index=False).\
       rolling(3, on='mo_yr', min_periods=1).\       
          mean().iloc[:,2:5].\
             add_suffix('_3mo').reset_index(drop=True,level=0)

df=pd.concat([df,s],axis=1)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X