在排序数组中查找百分位数



我正在编写一些代码,我想知道我是否正确计算了排序数组中的百分位数。目前,如果我想计算第 90 个百分位数,我会这样做:ARR[(9 * (N + 1((/10]。或者,假设我正在计算排序数组中的第 50 个百分位数,我这样做:ARR[(5 * (N + 1((/10]。更一般地说,为了计算第 x 个百分位数,我检查索引 [x/100 * (N + 1(],其中 N 是数组的大小。

这些似乎正在工作,但我只是在想是否有某种我错过的边缘情况。 例如,假设您只有 5 个元素。那么第 90 个百分位数应该是多少?它应该只是最大值吗?

提前致谢

例如,假设您只有 5 个元素。那么第 90 个百分位数应该是多少?它应该只是最大值吗?

是的。如果你按照这样的定义(这个只是从维基百科复制的(

N 个有序值列表的第 P 个百分位数(从最小到最大排序(是列表中的最小值,使得不超过 P %的数据严格小于该值,并且至少 P %的数据小于或等于该值

第 5 个元素可以是第 90 个百分位数:

  • 不超过 P %的数据严格小于值:80% 的数据严格小于最大元素,即不超过 90%
  • 至少 P %的数据小于或等于
  • 该值:100% 的数据小于或等于第 5 个元素,即至少 90%

第 5 个元素是可以做到这一点的最小元素(即使第 4 个和第 5 个元素相等,第 5 个元素仍然是最小的元素,因为百分位数是关于值的,而不是位置(。

对于微调公式,边界情况更有趣 - 例如 5 元素列表的第 79-80-81 个百分位数

element index:     0       1       2       3       4
strictly less:     0%     20%     40%     60%     80%
less or equal:    20%     40%     60%     80%    100%

第 79 个百分位数:预计第 4 个百分位数(60%<79%,79%<=80%( 第 80 个百分位数:预计第 4 个(60%<80%,80%<=80%( 第 81 个百分位数:预计第 5 个(80%<81%,81%<=100%(

这感觉就像向上舍入某些东西(分数指数((知道 80 是边界并查看映射 79->3、80->3 但 81->4(。该函数通常被称为类似ceil()Math.ceil()(问题指定目前没有编程语言(

P    5*P/100    ceil(5*P/100)     (5=N)
79      3.95        4
80      4           4
81      4.05        5

((N+1)会产生 4.74、4.8、4.86,所以可以肯定地说不需要+1(
因此ceil(N*P/100)似乎真的是那个(当然它也在维基百科上,仅比定义低 2-3 行(

请注意,编程语言可能会添加各种怪癖:

  • 数组/列表通常从 0 开始索引
  • ceil()的结果可能需要转换为整数
  • 还有一个偷偷摸摸的:如果NP是整数,您可能需要确保除法不是整数除法(自动丢弃分数部分,因此向下舍入结果(。

Java 行是这样的

int index=(int)Math.ceil(N*P/100.0)-1;

如果你想要第 0 个百分位数,它可以单独处理,或者与max()一起被黑到同一行

public static int percentile(int array[],float P) {
return array[Math.max(0,
Math.min(array.length, (int)Math.ceil(array.length*P/100))-1)];
}

(这个也使用min(),并且会为任何有限P产生一些结果,隐式地将其截断到 0<=P<=100 范围(

最新更新