如何在 JavaScript(或 PHP)中获取数组的中位数和四分位数/百分位数?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/48719873/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 08:13:37  来源:igfitidea点击:

How to get median and quartiles/percentiles of an array in JavaScript (or PHP)?

javascriptphpstatisticsmedianpercentile

提问by philippe

This question is turned into a Q&A, because I had struggle finding the answer, and think it can be useful for others

这个问题变成了问答,因为我很难找到答案,并认为它对其他人有用

I have a JavaScript array of valuesand need to calculate in JavaScript its Q2 (50th percentile aka MEDIAN), Q1 (25th percentile) and Q3 (75th percentile) values.

我有一个 JavaScript值数组,需要在 JavaScript 中计算它的 Q2(第 50 个百分点,又名MEDIAN)、Q1(第 25 个百分点)和第 3 个(第 75 个百分点)值。

enter image description here

在此处输入图片说明

回答by philippe

After searching for a long time, finding different versions that give different results, I found this nice snippet on Bastian P?ttner's web blog, but for PHP. For the same price, we get the averageand standard deviationof the data (for normal distributions)...

在搜索了很长时间后,找到了给出不同结果的不同版本,我在Bastian P?ttner 的网络博客上找到了这个不错的片段,但是对于PHP。对于相同的价格,我们得到数据的平均值标准差(对于正态分布)...

PHP Version

PHP版本

//from https://blog.poettner.de/2011/06/09/simple-statistics-with-php/

function Median($Array) {
  return Quartile_50($Array);
}

function Quartile_25($Array) {
  return Quartile($Array, 0.25);
}

function Quartile_50($Array) {
  return Quartile($Array, 0.5);
}

function Quartile_75($Array) {
  return Quartile($Array, 0.75);
}

function Quartile($Array, $Quartile) {
  sort($Array);
  $pos = (count($Array) - 1) * $Quartile;

  $base = floor($pos);
  $rest = $pos - $base;

  if( isset($Array[$base+1]) ) {
    return $Array[$base] + $rest * ($Array[$base+1] - $Array[$base]);
  } else {
    return $Array[$base];
  }
}

function Average($Array) {
  return array_sum($Array) / count($Array);
}

function StdDev($Array) {
  if( count($Array) < 2 ) {
    return;
  }

  $avg = Average($Array);

  $sum = 0;
  foreach($Array as $value) {
    $sum += pow($value - $avg, 2);
  }

  return sqrt((1 / (count($Array) - 1)) * $sum);
}

Based on the author's comments, I simply wrote a JavaScripttranslation that will certainly be useful, because surprisingly, it is nearly impossible to find a JavaScript equivalent on the web, and otherwise requires additional libraries like Math.js

根据作者的评论,我简单地写了一个肯定有用的JavaScript翻译,因为令人惊讶的是,几乎不可能在网络上找到等效的 JavaScript,否则需要像 Math.js 这样的额外库

JavaScript Version

JavaScript 版本

//adapted from https://blog.poettner.de/2011/06/09/simple-statistics-with-php/
function Median(data) {
  return Quartile_50(data);
}

function Quartile_25(data) {
  return Quartile(data, 0.25);
}

function Quartile_50(data) {
  return Quartile(data, 0.5);
}

function Quartile_75(data) {
  return Quartile(data, 0.75);
}

function Quartile(data, q) {
  data=Array_Sort_Numbers(data);
  var pos = ((data.length) - 1) * q;
  var base = Math.floor(pos);
  var rest = pos - base;
  if( (data[base+1]!==undefined) ) {
    return data[base] + rest * (data[base+1] - data[base]);
  } else {
    return data[base];
  }
}

function Array_Sort_Numbers(inputarray){
  return inputarray.sort(function(a, b) {
    return a - b;
  });
}

function Array_Sum(t){
   return t.reduce(function(a, b) { return a + b; }, 0); 
}

function Array_Average(data) {
  return Array_Sum(data) / data.length;
}

function Array_Stdev(tab){
   var i,j,total = 0, mean = 0, diffSqredArr = [];
   for(i=0;i<tab.length;i+=1){
       total+=tab[i];
   }
   mean = total/tab.length;
   for(j=0;j<tab.length;j+=1){
       diffSqredArr.push(Math.pow((tab[j]-mean),2));
   }
   return (Math.sqrt(diffSqredArr.reduce(function(firstEl, nextEl){
            return firstEl + nextEl;
          })/tab.length));  
}

回答by buboh

I updated the JavaScript translation from the first answer to use arrow functions and a bit more concise notation. The functionality remains mostly the same, except for std, which now computes the sample standard deviation (dividing by arr.length - 1instead of just arr.length)

我更新了第一个答案中的 JavaScript 翻译,以使用箭头函数和更简洁的符号。功能几乎保持不变,除了std,现在计算样本标准偏差(除以arr.length - 1而不仅仅是arr.length

// sort array ascending
const asc = arr => arr.sort((a, b) => a - b);

const sum = arr => arr.reduce((a, b) => a + b, 0);

const mean = arr => sum(arr) / arr.length;

// sample standard deviation
const std = (arr) => {
    const mu = mean(arr);
    const diffArr = arr.map(a => (a - mu) ** 2);
    return Math.sqrt(sum(diffArr) / (arr.length - 1));
};

const quantile = (arr, q) => {
    const sorted = asc(arr);
    const pos = (sorted.length - 1) * q;
    const base = Math.floor(pos);
    const rest = pos - base;
    if (sorted[base + 1] !== undefined) {
        return sorted[base] + rest * (sorted[base + 1] - sorted[base]);
    } else {
        return sorted[base];
    }
};

const q25 = arr => quantile(arr, .25);

const q50 = arr => quantile(arr, .50);

const q75 = arr => quantile(arr, .75);

const median = arr => q50(arr);