J'ai un cadre de données assez grand (3 millions de lignes) qui ressemble à ceci :
df = pd.DataFrame({'user_id' : ['100','101','102','103','104'],
'service_id' : ['73', '73', '46', '12', '12'],
'date_of_service' : ['2015-06-10 17:00:00',
'2014-09-27 17:00:00',
'2015-01-12 17:00:00',
'2012-08-22 17:00:00',
'2013-03-07 17:00:00']})
df
J'ai une colonne pour l'identification de l'utilisateur. Les utilisateurs fournissent des services, chaque service ayant un identifiant (service_id). Chaque service a une date (date_of_service).
Je voudrais créer une colonne qui calcule, pour chaque ligne, le nombre de services que l'utilisateur a effectués dans le passé (y compris le présent), c'est-à-dire que je voudrais le dataframe de résultat suivant :
df = pd.DataFrame({'user_id' : ['100','101','102','103','104'],
'service_id' : ['73', '73', '46', '12', '12'],
'date_of_service' : ['2015-06-10 17:00:00',
'2014-09-27 17:00:00',
'2015-01-12 17:00:00',
'2012-08-22 17:00:00',
'2013-03-07 17:00:00'],
'number_of_past_services' : [2, 1, 1, 1, 2]})
df
Ce que j'ai fait
J'ai utilisé un groupby et un count :
df['count_services'] = df.ix[:, 1:].groupby('user_id').transform('count')
Le problème est que, ici, je compte toutes les occurrences sur l'ensemble des données. Ce que je veux, c'est avoir les occurrences passées !
J'ai essayé de filtrer en utilisant des opérations de type sql, par exemple :
len(df[df.date_of_service < df['date_of_service'][0]][df.user_id == df.user_id[0]])
ce qui donne le bon résultat pour la première ligne. Cependant, ce calcul prend environ 1 seconde pour une seule ligne !
J'aimerais savoir comment mettre cela à l'échelle afin de pouvoir créer une colonne de manière efficace.