tc0*_*c03 7 javascript standard-deviation
我试图获得用户输入字符串的标准偏差.我有如下,但它返回错误的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);
}Run Code Online (Sandbox Code Playgroud)
<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>Run Code Online (Sandbox Code Playgroud)
这个 ES6 实现与 Excel 的内置STDEV.Pand STDEV.S(是调用.S时的默认值)相匹配。STDEV在此处传递true标志usePopulation将与 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)
);Run Code Online (Sandbox Code Playgroud)
如果您不喜欢很多代码,则可以从数组中获取标准差的简写方法:
const n = array.length;
const mean = array.reduce((a,b) => a+b)/n;
const s = Math.sqrt(array.map(x => Math.pow(x-mean,2)).reduce((a,b) => a+b)/n);
Run Code Online (Sandbox Code Playgroud)
对于正在寻求更通用解决方案的任何人,这是添加到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));
};
Run Code Online (Sandbox Code Playgroud)
我认为(主要)问题在于这一行:
v1 = parseFloat(Math.pow(temp[i]-mean),2);
Run Code Online (Sandbox Code Playgroud)
应该:
v1 = Math.pow(parseFloat(temp[i])-mean),2);
Run Code Online (Sandbox Code Playgroud)
您的代码尝试将字符串temp[i]作为数字使用并mean从中减去,然后对其进行平方,然后解析结果值.在计算中使用它之前需要parseFloat .此外,你还有一个,2关闭Math.pow呼叫的外部呼叫,因此平方也不会起作用.
使用更有意义的变量名称也会有所帮助,我的意思是,例如,你有一个名为"square"的变量来保存平方根操作的结果.
PS如果用户输入非数字数据,您需要添加一些错误检查.检查结果parseFloat()是不是NaN.我倾向于通过数组解析和检查有效数字进行初始循环,将解析后的数字存储在第二个数组中(或将它们写回第一个数组),如果有任何无效,则给用户一个错误消息在那一点上停下来.然后在实际计算中,您不必担心解析(或者,在您的情况下,在第二个循环中再次解析).
小智 5
function getStandardDeviation(numbersArr) {
// CALCULATE AVERAGE
var total = 0;
for(var key in numbersArr)
total += numbersArr[key];
var meanVal = total / numbersArr.length;
// CALCULATE AVERAGE
// 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-1));
// CALCULATE STANDARD DEVIATION
return SDresult;
}
var numbersArr = [10, 11, 12, 13, 14];
alert(getStandardDeviation(numbersArr));Run Code Online (Sandbox Code Playgroud)