Разница неуловима и обусловлена предположениями. Это проще всего объяснить с помощью трехэлементного случая. Предположим, у вас есть три элемента (N = 3) a=x[0] < b=x[1] < c=x[2]
. И Apache, и метод Excel говорят, что элемент b является 50-м процентилем (медиана). Однако они отличаются для a
и c
.
Метод Apache (и метод, на который ссылается страница NIST ), говорят: a
- это 25-й процентиль, а c
- это 75% -ный процентиль, потому что он делит пространство в N + 1 блоков, то есть в четверти.
Метод Excel говорит, что a
- это 0-й процентиль, а c
- 100-й процентиль, поскольку пространство разделено на N-1 блоков, то есть пополам.
Из-за этого, если вам нужен метод Excel и вы не хотите его кодировать самостоятельно, вы можете просто удалить самый маленький и самый большой элемент из вашего массива и вызвать метод Apache - он должен дать вам точно тот же результат за исключением процентилей за пределами конечных точек.
Если вы хотите закодировать это самостоятельно, простой способ приведен ниже. Помните об этих проблемах:
- сортирует массив (поэтому изменяет его)
- это занимает O (N log (N)) время из-за сортировки. В методе Apache используется алгоритм быстрого выбора, поэтому он занимает время O (N) (google "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;
}