Étant donné l'exemple de bloc de données suivant (totalement excessif)
import pandas as pd
import datetime as dt
df = pd.DataFrame({
"date" : [dt.date(2012, x, 1) for x in range(1, 11)],
"returns" : 0.05 * np.random.randn(10),
"dummy" : np.repeat(1, 10)
})
existe-t-il une méthode intégrée permettant d'appliquer deux fonctions d'agrégation différentes à la même colonne sans avoir à appeler agg
plusieurs fois?
La façon de le faire, syntaxiquement, mais intuitivement, serait la suivante:
# Assume `function1` and `function2` are defined for aggregating.
df.groupby("dummy").agg({"returns":function1, "returns":function2})
De toute évidence, Python n'autorise pas les clés en double. Existe-t-il un autre moyen d'exprimer l'entrée dans agg
? Peut-être qu'une liste de tuples [(column, function)]
fonctionnerait mieux pour autoriser plusieurs fonctions appliquées à la même colonne? Mais il semble qu’il n’accepte qu’un dictionnaire.
Existe-t-il une solution de contournement pour cela en plus de définir une fonction auxiliaire qui applique uniquement les deux fonctions internes? (Comment cela fonctionnerait-il avec l'agrégation de toute façon?)
Vous pouvez simplement passer les fonctions sous forme de liste:
In [20]: df.groupby("dummy").agg({"returns": [np.mean, np.sum]})
Out[20]:
returns
sum mean
dummy
1 0.285833 0.028583
ou comme dictionnaire:
In [21]: df.groupby('dummy').agg({'returns':
{'Mean': np.mean, 'Sum': np.sum}})
Out[21]:
returns
Sum Mean
dummy
1 0.285833 0.028583
Est-ce que quelque chose comme ce travail:
In [7]: df.groupby('dummy').returns.agg({'func1' : lambda x: x.sum(), 'func2' : lambda x: x.prod()})
Out[7]:
func2 func1
dummy
1 -4.263768e-16 -0.188565
Une façon évidente de le faire consiste à spécifier un nom de colonne de mappage de dictionnaire dans une liste de fonctions à agréger avec:
df.groupby("dummy").agg({'returns': [function1, function2]})
df.groupby("dummy").agg({'returns': ['sum', 'mean']})
returns
sum mean
dummy
1 0.328953 0.032895
Cependant, si vos fonctions ne fonctionnent que sur la colonne, la syntaxe est un peu plus simple: un dictionnaire n'est pas nécessaire si vous effectuez une agrégation sur une série:
df.groupby("dummy")['returns'].agg([function1, function2])
df.groupby('dummy')['returns'].agg(['sum', 'mean'])
sum mean
dummy
1 0.328953 0.032895
Cela élimine également le MultiIndex dans la sortie.
Dans les versions plus récentes des pandas, si vous utilisez un dictionnaire pour spécifier les noms de colonne pour la sortie d'agrégation, vous obtiendrez une FutureWarning
:
df.groupby('dummy').agg({'returns': {'Mean': 'mean', 'Sum': 'sum'}})
# FutureWarning: using a dict with renaming is deprecated and will be removed
# in a future version
L'utilisation d'un dictionnaire pour renommer des colonnes est obsolète en v0.20. Sur les versions plus récentes des pandas, ceci peut être spécifié plus simplement en passant une liste de n-uplets. Si vous spécifiez les fonctions de cette façon, les fonctions all de cette colonne doivent être spécifiées en tant que tuples de paires (nom, fonction).
df.groupby("dummy").agg({'returns': [('op1', 'sum'), ('op2', 'mean')]})
returns
op1 op2
dummy
1 0.328953 0.032895
Ou,
df.groupby("dummy")['returns'].agg([('op1', 'sum'), ('op2', 'mean')])
op1 op2
dummy
1 0.328953 0.032895