概要
在做图表的时候,经常会需要计算一组数据的百分位数是多少的问题。下面总结了两种计算百分位数的方法和区别,最后附上工具函数
例如:
计算出下面这组数据中的75百分位数:“[23.66, 4.52, 23.98, 9.34, 5.44]”
方法一
比较简单的一种方法,准确度欠佳,计算出的数值是原始数据中的某一个数字或者某两个相邻数字的平均数
const arr = [23.66, 4.52, 23.98, 9.34, 5.44];
//第一步,对数组进行排序(从小到大)
arr.sort((a,b)=>a-b)//arr 变为 [ 4.52, 5.44, 9.34, 23.66, 23.98 ]
// 第二步,计算指数i 0.75表示75百分位
const i = arr.length*0.75//3.75
//第三步,计算百分位数, 这里根据i的值会有两种处理方式。
//当i是整数时,取arr中第i-1和第i位数字的平均数;
//当i不是整数时,将i向上取整,然后取取整后的数字。
//当前例子中i=3.75,所以用第二种情况的计算方式
const result = arr[Math.ceil(i)-1]//23.66
方法二
较为准确的计算方法,是基于SPSS和SAS所使用的。它涉及到计算指数(n+1)P%=j+g,其中j为整数部分,g为小数部分。X表示排序后的数组,P百分位数=g*X(j+1)+(1-g)X(j)=X(j)+g[X(j+1)-X(j)],从公式可以得出,当g=0时,P百分位数=X(j)
const arr = [23.66, 4.52, 23.98, 9.34, 5.44];
//第一步,对数组进行排序(从小到大)
arr.sort((a,b)=>a-b)//arr 变为 [ 4.52, 5.44, 9.34, 23.66, 23.98 ]
// 第二步,计算指数i 0.75表示75百分位
const i = (arr.length+1)*0.75//4.5
// 第三步,判断i是否是整数,如果不是需要进一步计算出 j(整数部分) 和 g(小数部分)
let j,g;
if(Number.isInteger(i)){
j = i-1;
g = 0;
}else{
[j,g] = i.toString().split(".")
j=Number(j)
g=Number("0."+g)
}
//第四步,根据计算公式计算百分位数 P百分位数=X(j)+g[X(j+1)-X(j)],
//注意:X[j]=arr[j-1],数组下标是从0开始的,所以第j个数是arr[j-1]
const result = arr[j-1]+g*(arr[j]-arr[j-1])//23.82
小结
从上述两个结果来看,第一种方案更为简单一些,第二种更为精确一些。具体要使用哪种方法计算,是需要根据实际需求来的,最后再附上一个转换函数;觉得对你有用的话,记得点赞收藏+关注
/***
* 计算一组数据中的指定百分位数
* target:Array 源数据
* percentitle:0~1的数字 百分位
* type: 1|2 1表示简单算法 2表示精确算法
* */
function arr2px(target, percentile, type = 2) {
if (!Array.isArray(target) && target.length > 1) {
console.log('传入target参数和符合要求')
return
}
if (!(percentile > 0 && percentile < 1)) {
console.log('传入percentile参数和符合要求')
return
}
if (type !== 1 && type !== 2) {
console.log('传入type参数和符合要求')
return
}
const sortArr = target.toSorted((a, b) => a - b)
const n = sortArr.length
if (type === 1) {
const i = n * percentile;
if (Number.isInteger(i)) {
return (sortArr[i - 1] + sortArr[i]) / 5
} else {
return sortArr[Math.ceil(i) - 1]
}
} else {
debugger
const i = (n + 1) * percentile
let j, g;
if (Number.isInteger(i)) {
j = i, g = 0
} else {
[j, g] = (i + "").split(".");
j = +j, g = +("0." + g)
}
return sortArr[j - 1] + g * (sortArr[j] - sortArr[j - 1])
}
}
// test
const arr = [23.66, 4.52, 23.98, 9.34, 5.44];
const p1 = arr2px(arr, 0.75, 1)//23.66
const p2 = arr2px(arr, 0.75)//23.82
console.log(p1, p2)