我正在尝试获取用户输入字符串的标准差。我有如下,但它返回错误的 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>
如果您不喜欢大量代码,则可以使用从数组获取标准差的简便方法:
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)
}
对于任何寻求更通用解决方案的人来说,这里有一个添加到数组中的标准差函数#。该函数期望在数字数组上调用。
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));
};
此 ES6 实现与 Excel 内置的
STDEV.P
和 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)
);
我认为(主要)问题在这一行:
v1 = parseFloat(Math.pow(temp[i]-mean),2);
应该是:
v1 = Math.pow(parseFloat(temp[i])-mean,2);
您的代码尝试将
temp[i]
中的字符串用作数字并从中减去 mean
,然后对其求平方,然后解析结果值。需要在计算中使用它之前先解析Float。此外,您在 ,2
调用的右括号之外还有 Math.pow
,因此平方也不起作用。使用更有意义的变量名称也会有所帮助,我的意思是,例如,您有一个名为“square”的变量,它保存平方根运算的结果。
附注您需要添加一些错误检查,以防用户输入非数字数据。检查
parseFloat()
的结果是否不是
NaN
。我倾向于通过数组解析和检查有效数字进行初始循环,将解析后的数字存储在第二个数组中(或将它们写回第一个数组),如果有无效的数字,则向用户提供错误消息在那一点上停下来。然后在实际计算中,您不必担心解析(或者,在您的情况下,在第二个循环中再次解析)。
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));
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
);
};
更正标清版本:
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)
);
};
计算平均值
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 => parseFloat(s))
这是您的代码:
v1 = parseFloat(Math.pow(temp[i]-mean),2);
更正:
v1 = parseFloat(Math.pow((temp[i]-mean),2)); // (temp[i] - mean) all squared
export function getStandardDeviation(array: number[]) {
if (array.length < 2) {
return undefined;
}
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 - 1),
);
}
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)))
}