如何使用python/numpy计算百分位数?

Uri*_*Uri 193 python statistics numpy percentile numpy-ndarray

有没有一种方便的方法来计算序列或单维numpy数组的百分位数?

我正在寻找类似于Excel的百分位函数的东西.

我查看了NumPy的统计参考,但是找不到这个.我能找到的只是中位数(第50百分位数),但不是更具体的东西.

Jon*_*n W 254

您可能对SciPy Stats包感兴趣.它具有你所追求的百分位功能和许多其他统计好处.

percentile() numpy太.

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
Run Code Online (Sandbox Code Playgroud)

这张票让我相信他们不会percentile()很快融入numpy.

  • 到目前为止,numpy中存在百分位函数:http://docs.scipy.org/doc/numpy/reference/generated/numpy.percentile.html (16认同)
  • 谢谢!这就是它隐藏的地方.我知道scipy,但我想我认为像百分位数这样的简单事物会被构建成numpy. (2认同)

Bor*_*lik 69

顺便说一句,有一个纯Python的百分位函数实现,以防一个人不想依赖于scipy.该功能复制如下:

## {{{ 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/ }}}
Run Code Online (Sandbox Code Playgroud)

  • 我是上述食谱的作者.ASPN的一位评论者指出原始代码有一个bug.公式应为d0 = key(N [int(f)])*(ck); d1 =键(N [int(c)])*(kf).它已在ASPN上得到纠正. (48认同)
  • 对于那些甚至没有读过代码的人来说,在使用它之前,必须对N进行排序 (12认同)
  • @Wai Yip Tung,我修复了代码中的bug (6认同)
  • `percentile` 怎么知道用什么来表示 `N`?它没有在函数调用中指定。 (2认同)

ric*_*hie 25

import numpy as np
a = [154, 400, 1124, 82, 94, 108]
print np.percentile(a,95) # gives the 95th percentile
Run Code Online (Sandbox Code Playgroud)


Ash*_*kan 12

这里是如何在没有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)
Run Code Online (Sandbox Code Playgroud)

  • 是的,您必须先对列表进行排序:mylist = sorted(...) (2认同)

mpo*_*ett 11

百分I的定义中通常看到期望结果从所提供的列表中,低于该值的百分之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
Run Code Online (Sandbox Code Playgroud)

如果您希望从提供的列表中获取值,或者在其中找到P%的值,则使用以下简单修改:

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

或者@ijustlovemath建议的简化:

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


小智 6

检查scipy.stats模块:

 scipy.stats.scoreatpercentile
Run Code Online (Sandbox Code Playgroud)


Xav*_*hot 5

从开始Python 3.8,标准库随模块一起提供了该quantiles功能statistics

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
Run Code Online (Sandbox Code Playgroud)

quantiles对于给定的分布,返回将分位数间隔(以等概率分为连续间隔)distn - 1切点列表:ndistn

statistics.quantiles(dist,*,n = 4,method ='exclusive')

在那里n,在我们的案例(percentiles)是100

  • 只是一个注释。使用 method="exclusive" p99 可以大于原始列表中的最大值。如果这不是您想要的,即您想要 p100 = max,则使用 method="inclusive"。 (2认同)