如何在JavaScript(或PHP)中计算数组的中位数、四分位数/百分位数?
如何在JavaScript中计算数组的Q1、Q2(中位数)和Q3百分位数
我之前找这个问题的答案找了好久都没找到合适的,特意整理了这个解决方案,希望能帮到遇到同样问题的人。
要计算数值数组的四分位数,核心逻辑很清晰:先把数组排序,再根据百分位数的位置规则计算对应数值。下面是具体实现:
第一步:先对数组排序
四分位数的计算依赖有序数组,所以第一步必须把数组从小到大排序。注意Array.sort()默认是字符串排序,一定要传入数值比较函数:
const sortedArray = [...originalArray].sort((a, b) => a - b);
用扩展运算符[...originalArray]是为了不修改原数组,保留原始数据的完整性。
第二步:编写通用的百分位数计算函数
不同场景下百分位数的计算方式略有差异,这里采用线性插值法(行业常用的标准方式),逻辑如下:
- 计算目标索引:
index = (百分位数 / 100) * (数组长度 - 1) - 如果索引是整数,直接取对应位置的元素
- 如果索引是小数,取相邻两个元素的线性插值
对应的函数实现:
function calculatePercentile(arr, percentile) { const sorted = [...arr].sort((a, b) => a - b); const index = (percentile / 100) * (sorted.length - 1); const floorIndex = Math.floor(index); const ceilIndex = Math.ceil(index); // 索引为整数,直接返回对应元素 if (floorIndex === ceilIndex) { return sorted[floorIndex]; } // 索引为小数,计算线性插值 const fraction = index - floorIndex; return sorted[floorIndex] + fraction * (sorted[ceilIndex] - sorted[floorIndex]); }
第三步:计算Q1、Q2、Q3
有了通用函数,直接传入对应的百分位数即可:
const data = [12, 3, 5, 7, 19, 21, 4, 15]; // Q1(第25百分位数) const q1 = calculatePercentile(data, 25); // Q2(中位数,第50百分位数) const q2 = calculatePercentile(data, 50); // Q3(第75百分位数) const q3 = calculatePercentile(data, 75); console.log(`Q1: ${q1}, Q2: ${q2}, Q3: ${q3}`); // 输出:Q1: 4.75, Q2: 10, Q3: 17
补充:基于中位数的四分位数法
如果你的业务场景需要另一种计算逻辑(比如先取中位数拆分数组,再分别取子数组的中位数作为Q1/Q3),可以用下面的实现:
function calculateQuartiles(arr) { const sorted = [...arr].sort((a, b) => a - b); const mid = Math.floor(sorted.length / 2); // 计算中位数Q2 const q2 = sorted.length % 2 === 0 ? (sorted[mid - 1] + sorted[mid]) / 2 : sorted[mid]; // 拆分上下半部分数组 const lowerHalf = sorted.length % 2 === 0 ? sorted.slice(0, mid) : sorted.slice(0, mid); const upperHalf = sorted.length % 2 === 0 ? sorted.slice(mid) : sorted.slice(mid + 1); // 计算Q1 const q1 = lowerHalf.length % 2 === 0 ? (lowerHalf[Math.floor(lowerHalf.length / 2) - 1] + lowerHalf[Math.floor(lowerHalf.length / 2)]) / 2 : lowerHalf[Math.floor(lowerHalf.length / 2)]; // 计算Q3 const q3 = upperHalf.length % 2 === 0 ? (upperHalf[Math.floor(upperHalf.length / 2) - 1] + upperHalf[Math.floor(upperHalf.length / 2)]) / 2 : upperHalf[Math.floor(upperHalf.length / 2)]; return { q1, q2, q3 }; } // 示例使用 const result = calculateQuartiles(data); console.log(result); // { q1: 4.5, q2: 10, q3: 17 }
两种方法的结果略有差异,你可以根据业务需求选择合适的实现。
内容的提问来源于stack exchange,提问作者philippe
相关产品推荐
相关产品推荐

