d3.quantile似乎是错误地计算Q1

问题描述:

我给了一个24位数字的排序数组d3.quantile并要求它计算第一个四分位数值。由于阵列可以平均分为4组6个值,我的假设是结果将是arr [5]和arr [6]的平均值,但这不是我得到的。d3.quantile似乎是错误地计算Q1

var arr = [89.7, 93.2, 94, 94.3, 94.5, 95.4, 95.9, 96.1, 96.4, 96.5, 96.9, 96.9, 97.3, 97.6, 97.6, 97.6, 97.8, 98.3, 98.3, 98.4, 98.5, 98.5, 98.6, 98.6]; 
var myAssumption = (arr[5] + arr[6])/2; // 95.65 
var d3Result = d3.quantile(arr, 0.25);  // 95.775 

d3分位数函数是否使用更复杂的算法? This Wikipedia article列出了几个选项,但我不确定哪个正在使用(或为什么一个算法比另一个算法更好)。

结果并不正确,这是预期值。

如果你看那个Wikipedia页面链接你,你会看到在栏中的 “R-7”(这是写“R-7,Excel中,SciPy-(1,1),Maple- 6“)。这是d3.quantile()函数使用的算法。

看一看的d3.quantile()源代码:

export default function(values, p, valueof) { 
    if (valueof == null) valueof = number; 
    if (!(n = values.length)) return; 
    if ((p = +p) <= 0 || n < 2) return +valueof(values[0], 0, values); 
    if (p >= 1) return +valueof(values[n - 1], n - 1, values); 
    var n, 
     i = (n - 1) * p, 
     i0 = Math.floor(i), 
     value0 = +valueof(values[i0], i0, values), 
     value1 = +valueof(values[i0 + 1], i0 + 1, values); 
    return value0 + (value1 - value0) * (i - i0); 
} 

所以,你的情况,我们将有:

i = (24 - 1) * 0.25 
// ^--- the length of the array 

这让我们5.75(和5Math.floor(i))。

则返回值(这是value0 + (value1 - value0) * (i - i0)的功能)将是:

95.4 + (95.9 - 95.4) * (5.75 - 5) 

这给予我们您所看到的结果:

95.775 

这里是正在运行的演示:

var arr = [89.7, 93.2, 94, 94.3, 94.5, 95.4, 95.9, 96.1, 96.4, 96.5, 96.9, 96.9, 97.3, 97.6, 97.6, 97.6, 97.8, 98.3, 98.3, 98.4, 98.5, 98.5, 98.6, 98.6]; 
 
var d3Result = d3.quantile(arr, 0.25); 
 
console.log(d3Result)
<script src="https://d3js.org/d3.v4.min.js"></script>

+1

美丽的答案;谢谢! – carpiediem