Il est possible de renvoyer n'importe quel nombre de valeurs agrégées à partir d'un objet groupby avec apply
. Il suffit de renvoyer une série et les valeurs d'index deviendront les nouveaux noms de colonnes.
Voyons un exemple rapide :
df = pd.DataFrame({'group':['a','a','b','b'],
'd1':[5,10,100,30],
'd2':[7,1,3,20],
'weights':[.2,.8, .4, .6]},
columns=['group', 'd1', 'd2', 'weights'])
df
group d1 d2 weights
0 a 5 7 0.2
1 a 10 1 0.8
2 b 100 3 0.4
3 b 30 20 0.6
Définir une fonction personnalisée qui sera transmise à apply
. Il accepte implicitement un DataFrame - ce qui signifie que l'élément data
est un DataFrame. Remarquez qu'il utilise plusieurs colonnes, ce qui n'est pas possible avec la fonction agg
méthode groupby :
def weighted_average(data):
d = {}
d['d1_wa'] = np.average(data['d1'], weights=data['weights'])
d['d2_wa'] = np.average(data['d2'], weights=data['weights'])
return pd.Series(d)
Appelez le groupby apply
avec notre fonction personnalisée :
df.groupby('group').apply(weighted_average)
d1_wa d2_wa
group
a 9.0 2.2
b 58.0 13.2
Vous pouvez obtenir de meilleures performances en précalculant les totaux pondérés dans de nouvelles colonnes de DataFrame, comme expliqué dans d'autres réponses, et en évitant d'utiliser la fonction apply
tout à fait.