我必须在 JavaScript 中编写以下加权平均公式:
平均值 = (p1*p2*x1 + p3*p4*x2 + ... +p(n-2)*p(n-1)*xn) / (p1*p2 + p3*p4 + ... + p (n-2)p(n-1) )
该公式给出了值的平均值x
。
我还使用JavaScriptarray
填充了n
元素:
Array = (p1,p2,x1,p3,p4,x2....)
...我想找到平均值pi
的权重和值在哪里。xi
如何使用此数组编写公式?
我必须在 JavaScript 中编写以下加权平均公式:
平均值 = (p1*p2*x1 + p3*p4*x2 + ... +p(n-2)*p(n-1)*xn) / (p1*p2 + p3*p4 + ... + p (n-2)p(n-1) )
该公式给出了值的平均值x
。
我还使用JavaScriptarray
填充了n
元素:
Array = (p1,p2,x1,p3,p4,x2....)
...我想找到平均值pi
的权重和值在哪里。xi
如何使用此数组编写公式?
我可能会使用以下策略:
weights
和values
)。pn
's 并将结果推入weights
并推xn
入values
。换句话说,是这样的:
function weighted_average(input) {
var weights = [];
var values = [];
var weighted_total = 0;
var total_weight = 0;;
if (input.length % 3 !== 0) {
throw new Error("Input array length is not a multiple of 3.");
}
for (var i = 0; i < input.length; i += 3) {
weights.push(input[i] * input[i + 1]);
values.push(input[i + 2]);
}
for (var i = 0; i < weights.length; i += 1) {
weighted_total += weights[i] * values[i];
total_weight += weights[i];
}
return weighted_total / total_weight;
}
不过,您必须验证这是否完全符合您的要求。没有保证。;)
JSFiddle 演示:jsfiddle.net/Z8seZ
当然,您可以跳过中间数组以使其更快一些。但是上面的内容更明确,更易读,因此更易于维护(例如,您可以轻松拆分实际算法并为不同形式的输入创建不同的“包装器”函数)。如果使用(真正的)大型数据集,我只会优化它。
这是一种需要 ES5 的函数式方法:
var w = a.unzip(3).map(function(v, i, a) {
var weight = v[0] * v[1];
var sum = weight * v[2];
return [sum, weight];
}).reduce(function(p, c, i, a) {
return [p[0] + c[0], p[1] + c[1]];
}, [0, 0]);
var aw = w[0] / w[1];
在伪代码中是:
split the array into chunks of three
convert each three [p1, p2, x ] into a pair [ p1 * p2 * x , p1 * p2 ]
sum the pairs (along the array, not within each pair)
divide one by the other
unzip
以及将数组分块的(非标准)函数在哪里:
Object.defineProperty(Array.prototype, 'unzip', {
value: function(n) {
n = n || 2;
return this.reduce(function(p, c, i, a) {
if (i % n === 0) {
p.push(a.slice(i, i + n));
}
return p;
}, []);
}
});
xs
ES6 one-liner,用于包含键w
作为权重和v
值的对象数组:
((_w, _v) => _v / _w)(...xs.reduce((r, o) => [r[0] + o[w], r[1] + o[w] * o[v]], [0, 0]))