如何计算百分位数与Python / numpy的

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何计算百分位数与Python / numpy的相关的知识,希望对你有一定的参考价值。

参考技术A 1. 你可能会喜欢SciPy的统计软件包。它有百分函数你之后,许多其他统计好吃的东西。
此票证相信他们不会被整合percentile()到numpy的很快。
2.
顺便说一句,有百分函数的纯Python,万一一个不希望依赖于SciPy的。具体函数如下复制:
## CodeGo.net (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 CodeGo.net

3.
检查scipy.stats模块:
scipy.stats.scoreatpercentile
4.
import numpy as np
a = [154, 400, 1124, 82, 94, 108]
print np.percentile(a,95) # gives the 95th percentile

5.
百分看到定义预期结果从提供的列表,低于该值的百分之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被发现所提供的列表中获得的价值,这个简单的修改:
def percentile(N, P):
n = int(round(P * len(N) + 0.5))
if n > 1:
return N[n-2]
else:
return 0

6.
numpy.percentile
在那里我很想念?
7.
size=len(mylist)
p5=mylist[math.ceil((size*5)/100)-1]
p25=mylist[math.ceil((size*25)/100)-1]
p50=mylist[math.ceil((size*50)/100)-1]
p75=mylist[math.ceil((size*75)/100)-1]
p95=mylist[math.ceil((size*95)/100)-1]

从长数组计算百分位数?

【中文标题】从长数组计算百分位数?【英文标题】:Calculate percentile from a long array? 【发布时间】:2017-05-15 18:38:02 【问题描述】:

给定一长串以毫秒为单位的延迟,我想从中计算百分位数。我得到了下面的方法,但我不确定如何验证这是否给了我准确的结果?

  public static long[] percentiles(long[] latencies, double... percentiles) 
    Arrays.sort(latencies, 0, latencies.length);
    long[] values = new long[percentiles.length];
    for (int i = 0; i < percentiles.length; i++) 
      int index = (int) (percentiles[i] * latencies.length);
      values[i] = latencies[index];
    
    return values;
  

我想从latencies 数组中获取第 50、95、99 和 99.9 个百分位数。

long[] percs = percentiles(latencies, 0.5, 0.95, 0.99, 0.999);

在给定大量延迟的情况下,这是获得百分位数的正确方法吗?我正在使用 Java 7。

【问题讨论】:

请注意,您的 percentiles 方法不仅计算百分位值(并不总是正确 - 请参阅我的答案)并返回值,它还使 latencies 数组排序,这是一个可能不希望出现的副作用。这在您尝试编写的小程序中可能是无害的,但一般来说,如果方法具有不是该方法目的的副作用,则不是一个好习惯。 【参考方案1】:

这就是你要找的:

public static void main(String[] args) 
    List<Long> latencies = new List<Long>()  3, 6, 7, 8, 8, 9, 10, 13, 15, 16, 20 ;
    Collections.sort(latencies);

    System.out.println(percentile(latencies, 25));
    System.out.println(percentile(latencies, 50));
    System.out.println(percentile(latencies, 75));
    System.out.println(percentile(latencies, 100));


public static long percentile(List<Long> latencies, double percentile) 
    int index = (int) Math.ceil(percentile / 100.0 * latencies.size());
    return latencies.get(index-1);

【讨论】:

嗯,你注意到问题上的Java标签了吗? 快速翻译成java:public static double percentile(List&lt;Double&gt; values, double percentile) Collections.sort(values); int index = (int) Math.ceil((percentile / 100) * values.size()); return values.get(index - 1); 当百分位数为 0 时它会崩溃,但我猜这是边缘情况。【参考方案2】:
public static double percentile(double percentile, List<Double> items) 
    Preconditions.checkArgument(percentile >= 0);
    Preconditions.checkArgument(percentile <= 100);
    Preconditions.checkArgument(!items.isEmpty());

    Collections.sort(items);
    return items.get((int) Math.round(percentile / 100.0 * (items.size() - 1)));



@Test
public void test1() 
    List<Double> list = Arrays.asList(0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0);
    assertThat(percentile(0, list)).isEqualTo(0.0);
    assertThat(percentile(20, list)).isEqualTo(2.0);
    assertThat(percentile(80, list)).isEqualTo(8.0);
    assertThat(percentile(100, list)).isEqualTo(10.0);


@Test
public void test2() 
    List<Double> list = Arrays.asList(0.0, 1.0, 2.0, 3.0);
    assertThat(percentile(51, list)).isEqualTo(2.0);
    assertThat(percentile(49, list)).isEqualTo(1.0);


@Test
public void test3() 
    List<Double> list = Arrays.asList(42.0);     
    assertThat(percentile(0, list)).isEqualTo(42.0);
    assertThat(percentile(100, list)).isEqualTo(42.0);

【讨论】:

【参考方案3】:

根据Wikipedia,百分位数没有标准定义;但是,它们给出了一些可能的定义。您发布的代码似乎最接近最近排名方法,但并不完全相同。

他们给出的公式是

n = ceiling((P / 100) x N)

其中N 是列表的长度,P 是百分位数,n 是序数排名。您已经除以 100。看看他们给出的例子,很明显“序数排名”是列表中的索引,但它是 1-relative。因此,要获得 Java 数组的索引,您必须减去 1。因此,正确的公式应该是

n = ceiling(percentile * N) - 1

使用代码中的变量,Java 等效项是

(int) Math.ceil(percentiles[i] * latencies.length) - 1

这不是您编写的代码。当您将 double 转换为 int 时,结果会向 0 舍入,即它相当于“floor”函数。所以你的代码计算

floor(percentiles[i] * latencies.length)

如果percentiles[i] * latencies.length 不是整数,则结果相同。但是,如果是整数,使得“floor”和“ceiling”是相同的值,那么结果就会不同。

Wikipedia 中的一个示例是在列表为 15, 20, 35, 40, 50 时计算第 40 个百分位数。他们的答案是找到列表中的第二项,即 20,因为 0.40 * 5 = 2.0,并且上限 (2.0) = 2.0。

但是,您的代码:

int index = (int) (percentiles[i] * latencies.length);

将导致 index 为 2,这不是您想要的,因为这会给您列表中的第三项,而不是第二项。

因此,为了匹配 Wikipedia 定义,您的索引计算需要稍作修改。 (另一方面,如果有人过来说你的计算是正确的而***是错误的,我不会感到惊讶。我们会看到......)

【讨论】:

以上是关于如何计算百分位数与Python / numpy的的主要内容,如果未能解决你的问题,请参考以下文章

在Python中计算一次性计算多个百分位数percentilequantile

python中的百分位数[重复]

用于计算百分位数的纯 python 实现:这里的 lambda 函数有啥用?

python使用pandas中的groupby函数和agg函数计算每个分组数据的两个分位数(例如百分之10分位数和百分之90分位数)

如何在 numpy / scipy 中获取特定百分位数的索引?

python中如何计算百分数