Existe-t-il un moyen intégré à Pandas d'appliquer deux fonctions d'agrégation différentes f1, f2
à la même colonne df["returns"]
, sans avoir à appeler agg()
plusieurs fois?
Exemple de dataframe:
import pandas as pd
import datetime as dt
pd.np.random.seed(0)
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)
})
La manière syntaxiquement incorrecte, mais intuitivement correcte, de le faire serait:
# Assume `f1` and `f2` are defined for aggregating.
df.groupby("dummy").agg({"returns": f1, "returns": f2})
De toute évidence, Python n'autorise pas les clés en double. Existe-t-il une autre manière d'exprimer l'apport agg()
? Peut-être qu'une liste de tuples [(column, function)]
fonctionnerait mieux, pour autoriser plusieurs fonctions appliquées à la même colonne? Mais il agg()
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 simplement les deux fonctions à l'intérieur? (Comment cela fonctionnerait-il avec l'agrégation de toute façon?)
Réponses:
Vous pouvez simplement passer les fonctions sous forme de liste:
ou sous forme de dictionnaire:
la source
TLDR; Pandas
groupby.agg
a une nouvelle syntaxe plus simple pour spécifier (1) des agrégations sur plusieurs colonnes et (2) plusieurs agrégations sur une colonne. Donc, pour faire cela pour les pandas> = 0,25 , utilisezOU
Pandas> = 0,25: Agrégation nommée
Pandas a changé le comportement de
GroupBy.agg
en faveur d'une syntaxe plus intuitive pour spécifier les agrégations nommées. Consultez la section de documentation 0.25 sur les améliorations ainsi que les problèmes GitHub pertinents GH18366 et GH26512 .De la documentation,
Vous pouvez maintenant passer un tuple via des arguments de mot-clé. Les tuples suivent le format de
(<colName>, <aggFunc>)
.Alternativement, vous pouvez utiliser
pd.NamedAgg
(essentiellement un namedtuple) qui rend les choses plus explicites.C'est encore plus simple pour Series, il suffit de passer l'aggfunc à un argument mot-clé.
Enfin, si vos noms de colonnes ne sont pas des identifiants python valides, utilisez un dictionnaire avec décompression:
Pandas <0,25
Dans les versions plus récentes des pandas menant jusqu'à 0,24, si vous utilisez un dictionnaire pour spécifier les noms de colonne pour la sortie d'agrégation, vous obtiendrez un
FutureWarning
:L'utilisation d'un dictionnaire pour renommer les colonnes est obsolète dans la v0.20. Sur les versions plus récentes de pandas, cela peut être spécifié plus simplement en passant une liste de tuples. Si vous spécifiez les fonctions de cette manière, toutes les fonctions de cette colonne doivent être spécifiées sous forme de tuples de paires (nom, fonction).
Ou,
la source
df.groupby('kind')['height']
?df.groupby("kind").agg(**{ 'max height': pd.NamedAgg(column='height', aggfunc=max), 'min weight': pd.NamedAgg(column='weight', aggfunc=min) })
Quelque chose comme ce travail:
la source
aggregate
elle dit explicitement que quand adict
est passé, les clés doivent être des noms de colonnes. Donc, soit votre exemple est quelque chose que vous avez tapé sans vérifier cette erreur, soit Pandas rompt ses propres documents ici.returns
intérieur. Alors, c'est la version Series de l'agrégat? Je cherche à faire la version DataFrame de l'agrégat, et je souhaite appliquer plusieurs agrégations différentes à chaque colonne en même temps.