Come faccio a calcolare i percentili con Python / numpy?
-
24-09-2019 - |
Domanda
C'è un modo conveniente per percentili calcolare per una sequenza o di dimensioni singolo array NumPy?
Sto cercando qualcosa di simile alla funzione percentile di Excel.
Ho guardato in riferimento le statistiche di NumPy, e non riuscivo a trovare questo. Tutto quello che ho potuto trovare è la mediana (50 ° percentile), ma non qualcosa di più specifico.
Soluzione
Si potrebbe essere interessato al pacchetto SciPy Statistiche . Ha la funzione percentile siete dopo e molte altre chicche statistiche.
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
percentile()
questo biglietto mi porta a credere che non saranno integrando in NumPy presto in qualsiasi momento.
Altri suggerimenti
A proposito, c'è un puro- implementazione di Python della funzione percentile , nel caso in cui uno non vuole dipendere da SciPy. La funzione viene copiato di seguito:
## {{{ 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/ }}}
import numpy as np
a = [154, 400, 1124, 82, 94, 108]
print np.percentile(a,95) # gives the 95th percentile
Ecco come farlo senza NumPy, utilizzando solo python per calcolare il percentile.
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 definizione di percentile vedo solitamente aspetta come conseguenza il valore dall'elenco fornito sotto del quale si trovano P percentuale di valori ... che significa che il risultato deve essere dal set, non interpolazione tra elementi fissi. Per ottenere questo, è possibile utilizzare una funzione più semplice.
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
Se invece volete ottenere il valore dalla lista in dotazione o al di sotto, che P per cento dei valori si trovano, quindi utilizzare questa modifica semplice:
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 semplificazione suggerita da @ijustlovemath:
def percentile(N, P):
n = max(int(round(P * len(N) + 0.5)), 2)
return N[n-2]
Controlla scipy.stats modulo:
scipy.stats.scoreatpercentile
Per calcolare il percentile di una serie, eseguire:
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))
Ad esempio:
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}
Python 3.8
di partenza, la libreria standard viene fornito con la quantiles
funzione nell'ambito del statistics
modulo:
from statistics import quantiles
quantiles([1, 2, 3, 4, 5], n=100)
# [0.06, 0.12, 0.18, 0.24, 0.3, 0.36, 0.42, 0.48, 0.54, 0.6, 0.66, 0.72, 0.78, 0.84, 0.9, 0.96, 1.02, 1.08, 1.14, 1.2, 1.26, 1.32, 1.38, 1.44, 1.5, 1.56, 1.62, 1.68, 1.74, 1.8, 1.86, 1.92, 1.98, 2.04, 2.1, 2.16, 2.22, 2.28, 2.34, 2.4, 2.46, 2.52, 2.58, 2.64, 2.7, 2.76, 2.82, 2.88, 2.94, 3.0, 3.06, 3.12, 3.18, 3.24, 3.3, 3.36, 3.42, 3.48, 3.54, 3.6, 3.66, 3.72, 3.78, 3.84, 3.9, 3.96, 4.02, 4.08, 4.14, 4.2, 4.26, 4.32, 4.38, 4.44, 4.5, 4.56, 4.62, 4.68, 4.74, 4.8, 4.86, 4.92, 4.98, 5.04, 5.1, 5.16, 5.22, 5.28, 5.34, 5.4, 5.46, 5.52, 5.58, 5.64, 5.7, 5.76, 5.82, 5.88, 5.94]
quantiles([1, 2, 3, 4, 5], n=100)[49] # 50th percentile (e.g median)
# 3.0
quantiles
rendimenti per un dato distribuzione dist
un elenco di punti di taglio n - 1
separano gli intervalli n
quantile (divisione della dist
in intervalli continui n
con uguale probabilità):
statistics.quantiles (dist, *, n = 4, metodo = 'esclusiva')
dove n
, nel nostro caso (percentiles
) è 100
.
In caso di necessità la risposta ad essere un membro della matrice di input NumPy:
solo aggiungere che la funzione percentile in NumPy predefinita calcola l'uscita come media pesata lineare delle due voci vicine nel vettore di ingresso. In alcuni casi le persone potrebbero voler la tornati percentile per essere un vero e proprio elemento del vettore, in questo caso, da v1.9.0 in poi è possibile utilizzare l'opzione "interpolazione", sia con "inferiore", "superiore" o "più vicino".
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
Quest'ultimo è un effettivo ingresso nel vettore, mentre il primo è un'interpolazione lineare dei due voci vettoriali che confine percentile
per una serie: usato descrivere le funzioni
si supponga di avere df con i seguenti colonne vendite e id. si desidera calcolare i percentili per le vendite allora funziona in questo modo,
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