Я пытаюсь преобразовать следующий однопроходный код стандартного отклонения в C в Python:
double std_dev(double a[], int n) {
if(n == 0)
return 0.0;
int i = 0;
double meanSum = a[0];
double stdDevSum = 0.0;
for(i = 1; i < n; ++i) {
double stepSum = a[i] - meanSum;
double stepMean = ((i - 1) * stepSum) / i;
meanSum += stepMean;
stdDevSum += stepMean * stepSum;
}
// for poulation variance: return sqrt(stdDevSum / n);
return sqrt(stdDevSum / (n));
Вот что у меня есть на Python:
def std_dev(a,n):
if n == 0:
return 0.0
i = 0
meanSum = float(a[0])
stdDevSum = float(0.0)
for i in range(1,n,1):
stepSum = float(float(a[i]) - meanSum)
stepMean = float(((i - 1)*stepSum)/i)
meanSum += stepMean
stdDevSum += stepMean*stepSum
print(stdDevSum)
value = float(sqrt(stdDevSum/(n)))
print(value)
Однако я не получаю правильного результата для стандартного отклонения совокупности. Например, программа возвращает стандартное отклонение набора [10,20,500,40,50] как 175,33, тогда как онлайн-калькулятор или ручной расчет возвращает 188,53. Как объяснить разницу?
Спасибо!
Алгоритм C Источник: https://www.strchr.com/standard_deviation_in_one_pass
Каково наименьшее количество чисел, для которых вы обнаружили, что это не возвращает правильных результатов? Кто они такие? Прежде чем опубликовать здесь, вы распечатали значения каждой переменной и увидели, чем они отличаются между реализациями C и Python? На какой итерации происходит первое отклонение и в какой переменной? Отредактируйте вопрос, чтобы предоставить минимальный воспроизводимый пример.
Почему код Python имеет
sqrt(stdDevSum/(n)
, а код C имеетsqrt(stdDevSum / (n - 1)
?@Eric - я тоже спрашивал об этом, но потом увидел комментарий в конце кода C.
@AdrianMole: Тем не менее, код должен быть аналогичным. Код C с комментарием о том, что может быть получен другой результат, не эквивалентен коду Python, который дает другой результат.
@Eric Эрик, я согласен - ОП должен отредактировать, чтобы не было версии «образцовой сигмы», а только кода «популяционной сигмы».
Во всяком случае, мой ответ действительно решает проблему, которую вы впервые представили. Вы применили мое решение к своему вопросу и теперь задали новый вопрос. Ваше редактирование делает мой ответ недействительным, и это не то, как работает переполнение стека. Подумайте о том, чтобы отменить ваши правки (т. е. удалить мой предложенный ответ из вашего поста) и задать отдельный вопрос о том, почему сокращенный однопроходный алгоритм теряет точность.