【问题标题】:Standard deviation javascript标准差 javascript
【发布时间】:2011-11-12 17:17:27
【问题描述】:

我正在尝试获取用户输入字符串的标准偏差。我有以下内容,但它返回错误的 SD 值。计算应如下所示: 总和值/数值 = 平均值 平方(对每个值求和) 平方和/数值。

感谢协助(如果可能,请提供解释):

function sum() {
  var val = document.getElementById('userInput').value;
  var temp = val.split(" ");
  var total = 0;
  var v;
  var mean = total / temp.length;
  var total1 = 0;
  var v1;
  var temp23;
  var square;

  for (var i = 0; i < temp.length; i++) {
    v = parseFloat(temp[i]);
    total += v;
  }

  mean = total / temp.length;

  for (var i = 0; i < temp.length; i++) {
    v1 = parseFloat(Math.pow(temp[i] - mean), 2);
    total1 += v1;
  }


  temp23 = total1 / temp.length;
  square = Math.sqrt(temp23);

  document.write(total + '<br />');
  document.write(mean + '<br />');
  document.write(square);
}
<html>

<head>
</head>

<body>
  <form id="input">
    <textarea id="userInput" rows=20 cols=20></textarea>
    <input id="Run" type=Button value="run" onClick="sum()" />
  </form>
</body>

</html>

【问题讨论】:

  • 字符串没有标准偏差。你的意思是字符串中包含的一系列数字的标准差吗?

标签: javascript standard-deviation


【解决方案1】:

我认为(主要)问题在这一行:

v1 = parseFloat(Math.pow(temp[i]-mean),2);

应该是:

v1 = Math.pow(parseFloat(temp[i])-mean),2);

您的代码试图将temp[i] 中的字符串用作数字并从中减去mean,然后将其平方,然后解析结果值。需要 parseFloat before 在计算中使用它。此外,Math.pow 调用的右括号之外还有 ,2,因此平方也不起作用。

使用更有意义的变量名也会有所帮助,我的意思是,例如,您有一个名为“square”的变量,它保存平方根运算的结果。

附:如果用户输入非数字数据,您需要添加一些错误检查。检查parseFloat() 的结果是否不是NaN。我倾向于通过数组解析和检查有效数字进行初始循环,将解析的数字存储在第二个数组中(或将它们写回第一个数组),如果有任何无效,则给用户一条错误消息在那一点上停下来。然后在您的实际计算中,您不必担心在进行时进行解析(或者,在您的情况下,在第二个循环中再次解析)。

【讨论】:

    【解决方案2】:

    对于寻求更通用解决方案的任何人,这里是添加到 Array# 的标准偏差函数。该函数期望在一个数字数组上调用。

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

    【讨论】:

      【解决方案3】:

      function StandardDeviation(numbersArr) {
          //--CALCULATE AVAREGE--
          var total = 0;
          for(var key in numbersArr) 
             total += numbersArr[key];
          var meanVal = total / numbersArr.length;
          //--CALCULATE AVAREGE--
        
          //--CALCULATE STANDARD DEVIATION--
          var SDprep = 0;
          for(var key in numbersArr) 
             SDprep += Math.pow((parseFloat(numbersArr[key]) - meanVal),2);
          var SDresult = Math.sqrt(SDprep/numbersArr.length);
          //--CALCULATE STANDARD DEVIATION--
          alert(SDresult);
          
      }
      
      var numbersArr = [10, 11, 12, 13, 14];
      StandardDeviation(numbersArr);

      【讨论】:

      • 更正:此代码用于未更正的标准差;对于正确的标准偏差,使用“var SDresult = Math.sqrt(SDprep/(numbersArr.length-1));”而不是“var SDresult = Math.sqrt(SDprep/numbersArr.length);”
      【解决方案4】:

      如果您不喜欢大量代码,则从数组中获取标准差的简写方法:

      function getStandardDeviation (array) {
        const n = array.length
        const mean = array.reduce((a, b) => a + b) / n
        return Math.sqrt(array.map(x => Math.pow(x - mean, 2)).reduce((a, b) => a + b) / n)
      }
      

      【讨论】:

      • if (!array || array.length === 0) {return 0;} 避免除以 0
      【解决方案5】:

      标准差函数的快速实现:

      const sd = numbers => {
        const mean = numbers.reduce((acc, n) => acc + n) / numbers.length;
        return Math.sqrt(
          numbers.reduce((acc, n) => (n - mean) ** 2) / numbers.length
        );
      };
      
      

      更正的 SD 版本:

      const correctedSd = numbers => {
        const mean = numbers.reduce((acc, n) => acc + n) / numbers.length;
        return Math.sqrt(
          numbers.reduce((acc, n) => (n - mean) ** 2) / (numbers.length - 1)
        );
      };
      
      

      【讨论】:

      • 这不会产生正确的标准偏差。我刚刚测试了这个函数的输出与 LibreOffice Calc 的 stddev() 函数产生的结果,这个答案不匹配。而@Foxcode 上面的答案确实 会产生匹配结果:stackoverflow.com/a/53577159/1024832。 Math.js std() 函数也与此实现的结果不一致。
      • 然后删除长度 - 1 部分并仅使用长度。这会给你未更正的 SD。
      【解决方案6】:

      这个函数工作并产生与 numjs 相同的结果

      const st = (numbers) => {
        const mean = numbers.reduce((acc, item) => acc + item) / numbers.length;
        return Math.sqrt(numbers.reduce((acc, item) => acc + Math.pow((parseFloat(item) -mean), 2)))
      }

      【讨论】:

      • 我确实测试了这个函数,它没有给你标准偏差。来自@Foxcode 的The answer 工作。
      【解决方案7】:

      这个 ES6 实现匹配 Excel 的内置 STDEV.PSTDEV.S.S 是调用 STDEV 时的默认值)。在这里为usePopulation 传递true 标志将匹配Excel 的STDEV.P

      const standardDeviation = (arr, usePopulation = false) => {
        const mean = arr.reduce((acc, val) => acc + val, 0) / arr.length;
        return Math.sqrt(
          arr.reduce((acc, val) => acc.concat((val - mean) ** 2), []).reduce((acc, val) => acc + val, 0) /
            (arr.length - (usePopulation ? 0 : 1))
        );
      };
      
      console.log('STDEV.S =>',
        standardDeviation([
          10, 2, 38, 23, 38, 23, 21
        ])
      );
      
      console.log('STDEV.P =>',
        standardDeviation([
          10, 2, 38, 23, 38, 23, 21
        ], true)
      );

      Original Source

      【讨论】:

        【解决方案8】:

        标准差很简单。

        1. 计算平均值
        2. 将每个数字的减法与平均值平方。再次平均这些新数字以获得方差。
        3. 最后平方根方差得到标准差。
        function standardDeviation(numArray) {
          const mean = numArray.reduce((s, n) => s + n) / numArray.length;
          const variance = numArray.reduce((s, n) => s + (n - mean) ** 2, 0) / (numArray.length - 1);
          return Math.sqrt(variance);
        }
        

        如果你有一个字符串数组,记得先转换浮点数组array.map(s =&gt; parseFloat(s))

        【讨论】:

        • 它不会产生与 mathjs 相同的结果。为此,您必须在方差部分通过numArray.length -1 修复numArray.length
        • @throrin19 感谢您的更正。我将通过从长度中减去一个来修复它。
        【解决方案9】:

        你可以使用mathjs

        math.std(array)
        

        【讨论】:

          猜你喜欢
          • 2014-02-27
          • 2017-01-15
          • 1970-01-01
          • 2020-05-24
          • 2022-01-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-01-28
          相关资源
          最近更新 更多