Алгоритм на странице, на которую вы ссылаетесь , работает, вот рабочая реализация:
const calculateNewStats = (stats, newElement) => {
const newStats = {};
newStats.count = stats.count + 1;
newStats.min = Math.min(stats.min, newElement);
newStats.max = Math.max(stats.max, newElement);
newStats.avg = (stats.avg * stats.count + newElement) / newStats.count;
newStats.sd = Math.sqrt(
(
(newStats.count - 1) * stats.sd * stats.sd +
(newElement - newStats.avg) * (newElement - stats.avg)
) / (newStats.count)
);
return newStats;
};
// initial values
let stats = {
count: 0,
min: 0,
max: 0,
avg: 0,
sd: 0
};
let newElements = [1, 2, 3, 4, 0];
for (let newElement of newElements) {
stats = calculateNewStats(stats, newElement);
console.log(stats);
}
Результат на JSBin
Может быть, вы пропустили последнее предложение?
Если вы хотите, чтобы популяционная дисперсия или стандартное отклонение заменили N-1 на N и N-2 на N-1.
Примечание: будет небольшая потеря точности, которая будет увеличиваться по мере добавления элементов. Я бы посоветовал:
- сохранить дисперсию в
stats
вместе с sd
; сейчас я вычисляю квадратный корень из дисперсии, чтобы получить SD, затем возводя в квадрат SD, чтобы получить дисперсию в следующей итерации
- хранить общее значение в
stats
, вместо того, чтобы пересчитывать его с stats.avg * stats.count
на каждой итерации
Вы храните еще 2 числа в stats
, но вы должны получить более точные цифры.
Это лучшая реализация:
const calculateNewStats = (stats, newElement) => {
const newStats = {};
newStats.count = stats.count + 1;
newStats.total = stats.total + newElement;
newStats.min = Math.min(stats.min, newElement);
newStats.max = Math.max(stats.max, newElement);
newStats.avg = (stats.total + newElement) / newStats.count;
newStats.variance = (
(newStats.count - 1) * stats.variance +
(newElement - newStats.avg) * (newElement - stats.avg)
) / (newStats.count);
newStats.sd = Math.sqrt(newStats.variance);
return newStats;
};
// initial values
let stats = {
count: 0,
total: 0,
min: 0,
max: 0,
avg: 0,
sd: 0,
variance: 0
};
let newElements = [1, 2, 3, 4, 0];
for (let newElement of newElements) {
stats = calculateNewStats(stats, newElement);
console.log(stats);
}
JSBin