如何用python / numpy計算百分位數?



Answers

順便說一下,如果不想依靠scipy,就會出現純百分比函數的純Python實現 。 該功能複制如下:

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

有沒有一種方便的方法來計算序列或一維numpy數組的百分位數?

我正在尋找類似於Excel百分比函數的東西。

我查看了NumPy的統計參考,並找不到它。 我能找到的只是中位數(第50百分位),但沒有更具體的東西。




如果你需要答案是輸入numpy數組的成員:

只需要補充一下,numpy中的百分位數函數默認情況下將輸出計算為輸入向量中兩個相鄰條目的線性加權平均值。 在某些情況下,人們可能希望返回的百分位數是矢量的實際元素,在這種情況下,從v1.9.0開始,您可以使用“插值”選項,選擇“下”,“更高”或“最近”。

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

後者是向量中的實際條目,而前者是兩個與百分位數相鄰的向量條目的線性插值




下面是如何做到這一點沒有numpy,只使用python來計算百分比。

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)



我通常認為,百分位數的定義是所期望的結果,即所提供的列表中的值可以從下面找到百分之P的值,這意味著結果必須來自集合,而不是集合元素之間的內插。 為了得到這個,你可以使用一個更簡單的函數。

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

如果您希望從提供的列表中獲取價值的P值或低於該值的P百分比,請使用以下簡單的修改:

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

或者@ijustlovemath建議的簡化:

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



Links