Java Apache Commons getPercentile() 与 MS Excel 百分位数不同的结果

标签 java excel statistics apache-commons percentile

我有一个算法可以使用 Apache Commons 计算一系列值(12 个值)的 percentile(85),以便稍后使用阈值进行评估决定。结果与 Excel 给出的结果相似,但不相等,有时这对我的应用程序很重要,因为使用 excel 结果没有超过阈值,而使用 Java 中的 Apache Commons Math 则可以,所以我得到不同的输出。

这是一个例子:每 2 小时的互联网流量 (Mbps)

32,7076813360000000 41,2580429776000000 45,4453940200000000 48,8044409456000000 46,7462847936000000 49,8028100056000000 54,3719451144000000 41,9708134600000000 29,4371963240000000 22,4667255616000000 20,0388452248000000 28,7807757104000000

除以 1000 Mb(电缆的容量)后,我计算出职业的百分比 (85):

Excel:0,049153870117

Apache Commons 数学:0.05003126676104001

我发现可以使用 setPercentileImpl() 更改百分位数的实现(它不存在官方实现),但我找不到任何示例说明如何做这个,或者 Excel 算法(这是我被告知要实现的算法)。

欢迎提供有关此的任何帮助。

谢谢。

最佳答案

差异是微妙的,并且是由于假设。用 3 元素的情况最容易解释。假设你有三个元素(N=3)a=x[0] < b=x[1] < c=x[2] . Apache 和 Excel 方法都表示元素 b 是第 50 个百分位数(中位数)。然而,它们因 a 而不同。和 c .

Apache method (和 the method referenced by the NIST page )说 a是第 25 个百分位数,c是 75% 百分位数,因为它将空间分成 N+1 个 block ,即分成四分之一。

Excel 方法表示 a是第 0 个百分位数,c第 100 个百分位数,因为空间被分成 N-1 个 block ,即对半。

正因为如此,如果您想要 Excel 方法并且不想自己编写代码,您可以只从数组中删除最小和最大的元素,然后调用 Apache 方法 - 它应该会给您准确的除了终点以外的百分位数,结果相同。

如果您想自己编写代码,下面提供了一种简单的方法。请注意这些问题:

  • 这对数组进行了排序(因此改变了它)
  • 由于排序,这需要 O(N log(N)) 时间。 Apache 方法使用快速选择算法,因此需要 O(N) 时间(如果您想了解更多信息,请谷歌“quickselect”)

代码(未经测试甚至未编译,但应该给您一个想法)。

// warning - modifies data 
double excelPercentile(double [] data, double percentile) { array
    Arrays.sort(data);
    double index = percentile*(data.length-1);
    int lower = (int)Math.floor(index);
    if(lower<0) { // should never happen, but be defensive
       return data[0];
    }
    if(lower>=data.length-1) { // only in 100 percentile case, but be defensive
       return data[data.length-1);
    }
    double fraction = index-lower;
    // linear interpolation
    double result=data[lower] + fraction*(data[lower+1]-data[lower]);
    return result;
 }

关于Java Apache Commons getPercentile() 与 MS Excel 百分位数不同的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5948146/

相关文章:

Java - 什么时候释放直接缓冲区?

c++ - 适用于 Mac 的 Excel SDK

iphone - 按手机代数划分的 iPhone 用户分割

excel - 如何通过 ADO/ODBC 访问 Excel 命名表?

excel - 如何使用偏移量使用 VBA 扩展命名范围

excel - 使用 PL/SQL 的 Excel 中 NORMDIST 函数的等价物

python - 如何在 matplotlib (python) 中制作带有 r 值和回归函数的图例?

java - 我应该重写 Object.equals(Object) 方法吗?

java - 图像 URL 转二进制

java - Android java ImageButton 方法帮助