88 votes

Passer les percentiles à la fonction agg de pandas

Je veux passer le numpy percentile() par l'intermédiaire de la fonction agg() comme je le fais ci-dessous avec diverses autres fonctions statistiques numpy.

Actuellement, j'ai un cadre de données qui ressemble à ceci :

AGGREGATE   MY_COLUMN
A           10
A           12
B           5
B           9
A           84
B           22

Et mon code ressemble à ceci :

grouped = dataframe.groupby('AGGREGATE')
column = grouped['MY_COLUMN']
column.agg([np.sum, np.mean, np.std, np.median, np.var, np.min, np.max])

Le code ci-dessus fonctionne, mais je veux faire quelque chose comme

column.agg([np.sum, np.mean, np.percentile(50), np.percentile(95)])

C'est-à-dire, spécifier les différents percentiles à retourner à partir de agg() .

Comment faire ?

128voto

Andy Hayden Points 38010

Ce n'est peut-être pas très efficace, mais une solution serait de créer vous-même une fonction :

def percentile(n):
    def percentile_(x):
        return np.percentile(x, n)
    percentile_.__name__ = 'percentile_%s' % n
    return percentile_

Incluez-le ensuite dans votre agg :

In [11]: column.agg([np.sum, np.mean, np.std, np.median,
                     np.var, np.min, np.max, percentile(50), percentile(95)])
Out[11]:
           sum       mean        std  median          var  amin  amax  percentile_50  percentile_95
AGGREGATE
A          106  35.333333  42.158431      12  1777.333333    10    84             12           76.8
B           36  12.000000   8.888194       9    79.000000     5    22             12           76.8

Notez bien que c'est ainsi devrait être fait cependant...

57voto

Arun Nalpet Points 528

Vous pouvez avoir agg() utiliser une fonction personnalisée à exécuter sur la colonne spécifiée :

# 50th Percentile
def q50(x):
    return x.quantile(0.5)

# 90th Percentile
def q90(x):
    return x.quantile(0.9)

my_DataFrame.groupby(['AGGREGATE']).agg({'MY_COLUMN': [q50, q90, 'max']})

30voto

MonkeyButter Points 229

Pour être plus précis, si vous souhaitez simplement agréger les résultats de votre groupby pandas à l'aide de la fonction percentile, la fonction lambda de python offre une solution assez intéressante. En utilisant la notation de la question, l'agrégation par le percentile 95, devrait être :

dataframe.groupby('AGGREGATE').agg(lambda x: np.percentile(x['COL'], q = 95))

Vous pouvez également affecter cette fonction à une variable et l'utiliser en conjonction avec d'autres fonctions d'agrégation.

17voto

scottlittle Points 4898

Essayez ceci pour les percentiles de 50% et 95% :

column.describe(percentiles=[0.5, 0.95])

16voto

Thomas Points 1141

J'aime vraiment la solution qu'Andy Hayden a donnée Cependant, j'ai eu de nombreux problèmes avec ce produit :

  • Si le cadre de données a plusieurs colonnes, est-il agrégé sur les colonnes plutôt que sur les lignes ?
  • Pour moi, les noms des lignes étaient percentile_0.5 (point au lieu du trait de soulignement). Je ne suis pas sûr de la cause de ce problème, probablement parce que j'utilise Python 3.
  • Nécessité d'importer numpy également au lieu de rester dans pandas (je sais, numpy est importé implicitement dans pandas...)

Voici une version mise à jour qui corrige ces problèmes :

def percentile(n):
    def percentile_(x):
        return x.quantile(n)
    percentile_.__name__ = 'percentile_{:2.0f}'.format(n*100)
    return percentile_

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