¿Cómo calculo los percentiles con python / numpy?

¿Existe una manera conveniente de calcular los percentiles para una secuencia o una matriz numpy unidimensional?

Estoy buscando algo similar a la función de percentil de Excel.

Busqué en la referencia de estadísticas de NumPy, y no pude encontrar esto. Todo lo que pude encontrar es la mediana (percentil 50), pero no algo más específico.

Quizás te interese el paquete de estadísticas de SciPy . Tiene la función de percentil que está buscando y muchos otros beneficios estadísticos.

percentile() está disponible en numpy también.

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

Este boleto me lleva a creer que no integrarán percentile() en números en el corto plazo.

Por cierto, hay una implementación Python pura de la función de percentil , en caso de que uno no quiera depender de scipy. La función se copia a continuación:

 ## {{{ 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)]) * (ck) d1 = key(N[int(c)]) * (kf) return d0+d1 # median is 50th percentile. median = functools.partial(percentile, percent=0.5) ## end of http://code.activestate.com/recipes/511478/ }}} 
 import numpy as np a = [154, 400, 1124, 82, 94, 108] print np.percentile(a,95) # gives the 95th percentile 

Aquí se explica cómo hacerlo sin adormecer, usando solo Python para calcular el percentil.

 import math def percentile(data, percentile): size = len(data) return sorted(data)[int(math.ceil((size * percentile) / 100)) - 1] p5 = percentile(mylist, 5) p25 = percentile(mylist, 25) p50 = percentile(mylist, 50) p75 = percentile(mylist, 75) p95 = percentile(mylist, 95) 

La definición de percentil que generalmente veo espera, como resultado, el valor de la lista suministrada debajo de la cual se encuentra el porcentaje de P de los valores … lo que significa que el resultado debe ser del conjunto, no una interpolación entre los elementos establecidos. Para conseguir eso, puedes usar una función más 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 prefiere obtener el valor de la lista suministrada en o por debajo de la cual se encuentra el P por ciento de los valores, use esta simple modificación:

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

O con la simplificación sugerida por @ijustlovemath:

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

compruebe el módulo scipy.stats:

  scipy.stats.scoreatpercentile 

Para calcular el percentil de una serie, ejecute:

 from scipy.stats import rankdata import numpy as np def calc_percentile(a, method='min'): if isinstance(a, list): a = np.asarray(a) return rankdata(a, method=method) / float(len(a)) 

Por ejemplo:

 a = range(20) print {val: round(percentile, 3) for val, percentile in zip(a, calc_percentile(a))} >>> {0: 0.05, 1: 0.1, 2: 0.15, 3: 0.2, 4: 0.25, 5: 0.3, 6: 0.35, 7: 0.4, 8: 0.45, 9: 0.5, 10: 0.55, 11: 0.6, 12: 0.65, 13: 0.7, 14: 0.75, 15: 0.8, 16: 0.85, 17: 0.9, 18: 0.95, 19: 1.0} 

En caso de que necesite que la respuesta sea un miembro de la matriz numpy de entrada:

Solo para agregar que la función de percentil en numpy por defecto calcula la salida como un promedio ponderado lineal de las dos entradas vecinas en el vector de entrada. En algunos casos, es posible que las personas deseen que el percentil devuelto sea un elemento real del vector, en este caso, a partir de la v1.9.0 puede usar la opción “interpolación”, ya sea con “más bajo”, “más alto” o “más cercano”.

 import numpy as np x=np.random.uniform(10,size=(1000))-5.0 np.percentile(x,70) # 70th percentile 2.075966046220879 np.percentile(x,70,interpolation="nearest") 2.0729677997904314 

La última es una entrada real en el vector, mientras que la primera es una interpolación lineal de dos entradas de vectores que bordean el percentil

Para una serie: utilizar funciones de describir.

Supongamos que tiene df con las siguientes columnas sales e id. quieres calcular los percentiles para las ventas, entonces funciona así,

 df['sales'].describe(percentiles = [0.0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1]) 0.0: .0: minimum 1: maximum 0.1 : 10th percentile and so on