2010-03-03 23 views
135

Gibt es eine bequeme Möglichkeit, Perzentile für eine Sequenz oder eindimensionales numpy Array zu berechnen?Wie berechne ich Perzentile mit Python/Numpy?

Ich bin auf der Suche nach etwas ähnlich Perzentil-Funktion von Excel.

Ich sah in NumPy Statistik Referenz und konnte dies nicht finden. Alles, was ich finden konnte, ist der Median (50. Perzentil), aber nicht etwas Spezifischeres.

Antwort

182

Sie könnten das SciPy Stats Paket interessiert sein. Es hat the percentile function du bist nach und viele andere statistische Goodies.

percentile()is available in numpy zu.

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 

This ticket führt mich sie percentile() in numpy jederzeit auf die Integration bald nicht zu glauben.

+2

Thank you! Da hat es sich versteckt. Ich war mir über Scipy im Klaren, aber ich vermutete, dass einfache Dinge wie Perzentile in eine Menge eingebaut würden. – Uri

+14

Inzwischen existiert eine Perzentilfunktion in numpy: http://docs.scipy.org/doc/numpy/reference/generated/numpy.percentile.html – Anaphory

+1

Sie können es auch als eine Aggregationsfunktion verwenden, z. Um das zehnte Perzentil jeder Gruppe einer Wertspalte nach Schlüssel zu berechnen, verwenden Sie 'df.groupby ('key') [['value']]. agg (lambda g: np.perzentil (g, 10))' – patricksurry

51

Übrigens gibt es a pure-Python implementation of percentile function, falls man nicht auf scipy angewiesen ist. Die Funktion wird im Folgenden wiedergegeben:

## {{{ 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/ }}} 
+39

Ich bin der Autor des obigen Rezept.Ein Kommentator in ASPN hat darauf hingewiesen, dass der ursprüngliche Code einen Fehler aufweist. Die Formel sollte d0 = Schlüssel sein (N [int (f)]) * (c-k); d1 = Schlüssel (N [int (c)]) * (k-f). Es wurde auf ASPN korrigiert. –

+6

@Wai Yip Tung, ich reparierte den Fehler im Code –

+1

Wie weiß 'Perzentil', was man für' N' verwendet? Es ist nicht im Funktionsaufruf angegeben. – Richard

7

Check für scipy.stats Modul:

scipy.stats.scoreatpercentile 
8

Die Definition des Begriffs Perzentil erwartet ich sehe, in der Regel als Ergebnis den Wert aus der bereitgestellten Liste, unter dem P Prozent der Werte gefunden werden ... was bedeutet, dass das Ergebnis aus der Menge stammen muss, nicht eine Interpolation zwischen Mengenelementen. Um das zu erreichen, können Sie eine einfachere Funktion verwenden.

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 

Wenn Sie lieber den Wert von der mitgelieferten Liste bekommen würden bei oder unter der P Prozent der Werte gefunden werden, dann diese einfache Modifikation verwenden:

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

Oder mit der Vereinfachung von @ijustlovemath vorgeschlagen :

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

danke, ich erwarte auch Perzentil/Median zu tatsächlichen Werten aus den Sätzen und nicht Interpolationen – hansaplast

+0

Hallo @mpounsett. Danke für den oberen Code. Warum gibt Ihr Perzentil immer ganzzahlige Werte zurück? Die Perzentilfunktion sollte das N-te Perzentil einer Liste von Werten zurückgeben, und dies kann auch eine Gleitkommazahl sein. Zum Beispiel gibt die Excel '' 'PERCENTILE'' Funktion die folgenden Perzentilen für Ihre oberen Beispiele zurück:' '' 3.7 = Perzentil (A, P = 0.3) '' '' '' 0.82 = Perzentil (A, P = 0.8) '' ',' '' 20 = Perzentil (B, P = 0.3) '' ',' '' 42 = Perzentil (B, P = 0.8) '' '. – marco

+0

Es wird im ersten Satz erklärt. Die üblichere Definition von Perzentil ist, dass es die Zahl in einer Reihe ist, unter der P Prozent der Werte in der Reihe gefunden werden. Da dies die Indexnummer eines Elements in einer Liste ist, kann es kein Float sein. – mpounsett

5

Hier ist, wie es ohne numpy, nur mit Python, um das Perzentil zu berechnen.

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) 
+0

dies funktioniert nur, wenn die Daten bestellt werden – otmezger

+2

Ja, Sie müssen die Liste vorher sortieren: mylist = sortiert (...) – Ashkan

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

Um die Perzentil einer Reihe zu berechnen, führen:

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)) 

Zum Beispiel:

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} 
Verwandte Themen