265 votes

Comment calculer les percentiles avec python/numpy ?

Existe-t-il un moyen pratique de calculer les percentiles pour une séquence ou un tableau numpy unidimensionnel ?

Je cherche quelque chose de similaire à la fonction percentile d'Excel.

J'ai regardé dans la référence des statistiques de NumPy, et je n'ai pas trouvé ça. Tout ce que j'ai pu trouver est la médiane (50e percentile), mais pas quelque chose de plus spécifique.

0 votes

Une question connexe sur le calcul des percentiles à partir des fréquences : stackoverflow.com/questions/25070086/

352voto

Jon W Points 7032

Vous pourriez être intéressé par le Statistiques SciPy paquet. Il a la fonction percentile que vous recherchez et de nombreuses autres statistiques.

percentile() est disponible sur numpy aussi.

import numpy as np
a = np.array([1,2,3,4,5])
p = np.percentile(a, 50) # return 50th percentile, e.g median.
print p
3.0

Ce billet me pousse à croire qu'ils ne seront pas intégrés percentile() dans numpy de sitôt.

2 votes

Merci ! C'est donc là qu'il se cachait. Je connaissais scipy mais je suppose que je pensais que des choses simples comme les percentiles seraient intégrées dans numpy.

19 votes

A présent, une fonction percentile existe dans numpy : docs.scipy.org/doc/numpy/reference/generated/

1 votes

Vous pouvez également l'utiliser comme fonction d'agrégation, par exemple pour calculer le dixième percentile de chaque groupe d'une colonne de valeurs par clé, utilisez df.groupby('key')[['value']].agg(lambda g: np.percentile(g, 10))

83voto

bgbg Points 4713

Au fait, il y a une implémentation purement Python de la fonction percentile dans le cas où l'on ne veut pas dépendre de scipy. La fonction est copiée ci-dessous :

## {{{ http://code.activestate.com/recipes/511478/ (r1)
import math
import functools

def percentile(N, percent, key=lambda x:x):
    """
    Find the percentile of a list of values.

    @parameter N - is a list of values. Note N MUST BE already sorted.
    @parameter percent - a float value from 0.0 to 1.0.
    @parameter key - optional key function to compute value from each element of N.

    @return - the percentile of the values
    """
    if not N:
        return None
    k = (len(N)-1) * percent
    f = math.floor(k)
    c = math.ceil(k)
    if f == c:
        return key(N[int(k)])
    d0 = key(N[int(f)]) * (c-k)
    d1 = key(N[int(c)]) * (k-f)
    return d0+d1

# median is 50th percentile.
median = functools.partial(percentile, percent=0.5)
## end of http://code.activestate.com/recipes/511478/ }}}

64 votes

Je suis l'auteur de la recette ci-dessus. Un commentateur de l'ASPN m'a signalé que le code original comporte un bug. La formule devrait être d0 = clé(N[int(f)]) * (c-k) ; d1 = clé(N[int(c)]) * (k-f). Elle a été corrigée sur ASPN.

2 votes

Comment percentile savoir ce qu'il faut utiliser pour N ? Ce n'est pas spécifié dans l'appel de la fonction.

19 votes

Pour ceux qui n'ont même pas lu le code, avant de l'utiliser, il faut trier N

35voto

richie Points 664
import numpy as np
a = [154, 400, 1124, 82, 94, 108]
print np.percentile(a,95) # gives the 95th percentile

13voto

mpounsett Points 381

La définition du percentile que je vois habituellement attend comme résultat la valeur de la liste fournie en dessous de laquelle se trouvent P pour cent des valeurs... ce qui signifie que le résultat doit provenir de l'ensemble, et non d'une interpolation entre les éléments de l'ensemble. Pour obtenir cela, vous pouvez utiliser une fonction plus simple.

def percentile(N, P):
    """
    Find the percentile of a list of values

    @parameter N - A list of values.  N must be sorted.
    @parameter P - A float value from 0.0 to 1.0

    @return - The percentile of the values.
    """
    n = int(round(P * len(N) + 0.5))
    return N[n-1]

# A = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
# B = (15, 20, 35, 40, 50)
#
# print percentile(A, P=0.3)
# 4
# print percentile(A, P=0.8)
# 9
# print percentile(B, P=0.3)
# 20
# print percentile(B, P=0.8)
# 50

Si vous préférez obtenir la valeur de la liste fournie à laquelle ou en dessous de laquelle P pour cent des valeurs sont trouvées, utilisez cette simple modification :

def percentile(N, P):
    n = int(round(P * len(N) + 0.5))
    if n > 1:
        return N[n-2]
    else:
        return N[0]

Ou avec la simplification suggérée par @ijustlovemath :

def percentile(N, P):
    n = max(int(round(P * len(N) + 0.5)), 2)
    return N[n-2]

0 votes

Merci, je m'attends également à ce que les percentiles/médianes résultent de valeurs réelles des ensembles et non d'interpolations.

1 votes

Salut @mpounsett. Merci pour le code supérieur. Pourquoi votre percentile retourne-t-il toujours des valeurs entières ? La fonction percentile doit retourner le N-ième percentile d'une liste de valeurs, et cela peut aussi être un nombre flottant. Par exemple, la fonction Excel PERCENTILE renvoie les percentiles suivants pour vos exemples supérieurs : 3.7 = percentile(A, P=0.3) , 0.82 = percentile(A, P=0.8) , 20 = percentile(B, P=0.3) , 42 = percentile(B, P=0.8) .

1 votes

C'est expliqué dans la première phrase. La définition la plus courante du percentile est qu'il s'agit du nombre dans une série en dessous duquel se trouvent P pour cent des valeurs de la série. Comme il s'agit du numéro d'index d'un élément d'une liste, il ne peut s'agir d'un flottant.

6voto

Evert Points 61

Vérification du module scipy.stats :

 scipy.stats.scoreatpercentile

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