предупреждение sqrt: вызывается с отрицательным аргументом в GNU AWK - PullRequest
0 голосов
/ 09 января 2020

Я пытаюсь вычислить стандартное отклонение для всех столбцов, доступных в следующем файле.

Inputfile:

2017  04 15 00 00 00    36.606  -97.488  316.200      233.230  0.10      950.840  0.40
2017  04 15 00 00 01    36.606  -97.488  316.200      245.220  0.10      911.540  0.40
2017  04 15 00 00 02    36.606  -97.488  316.200      246.460  0.10      958.790  0.40
2017  04 15 00 00 03    36.606  -97.488  316.200      216.880  0.10      902.750  0.40
2017  04 15 00 00 04    36.606  -97.488  316.200      213.280  0.10      854.170  0.40
2017  04 15 00 00 05    36.606  -97.488  316.200      200.360  0.10      879.040  0.40
2017  04 15 00 00 06    36.606  -97.488  316.200      204.250  0.10      951.800  0.40
2017  04 15 00 00 07    36.606  -97.488  316.200      224.270  0.10     1015.570  0.40
2017  04 15 00 00 08    36.606  -97.488  316.200      203.490  0.10      849.640  0.40
2017  04 15 00 00 09    36.606  -97.488  316.200      198.620  0.10      969.190  0.40
2017  04 15 00 00 10    36.606  -97.488  316.200      213.530  0.10      896.930  0.40
2017  04 15 00 00 10    36.606  -97.488  316.200      216.300  0.10     1005.490  0.40

Я рассчитываю стандартное отклонение для всех столбцов, используя следующую строку:

awk '{for(i=1;i<=NF;i++){a[i]+=$i; s[i]+=$i*$i}}END{for(i=1;i<=NF;i++) {print sqrt(s[i]/NR-(a[i]/NR)^2)}}' infile > outfile

Это рассчитывает стандартное отклонение всех столбцов в соответствии с моим требованием. Но когда я использовал gnu awk (gawk) вместо awk, это вычисляет то же самое, но со следующим предупреждением:

awk: cmd. line:1: (FILENAME=infile FNR=3600) warning: sqrt: called with a negative argument -5.63438e-15

Я не могу понять, что различие между awk и gawk дает мне это предупреждение.

Спасибо

1 Ответ

0 голосов
/ 09 января 2020

По определению, дисперсия (квадрат стандартного отклонения) входных данных рассчитывается по следующему уравнению:

enter image description here

Проблема здесь заключается в среднее (x-bar) значение не может быть определено , пока все данные не будут прочитаны. Поэтому предполагается, что приведенное выше уравнение не подходит для фактической реализации.
На практике это уравнение преобразуется в:

enter image description here

, что подходит для расчета по данным.

Хотя эти уравнения теоретически эквивалентны , второе может привести к отрицательному значению из-за ошибок округления. Это может произойти, если все данные идентичны ( независимо от самого значения ).

Возможный обходной путь - установить отклонение равным нулю для отрицательного значения, как я отметил в комментарии. , Другой обходной путь - go, возвращающийся к исходному определению с:

awk 'NR==FNR {
    for (i=1; i<=NF; i++)
        sum[i]+=$i
    next
}
# following lines are executed in the 2nd iteration
FNR==1 {
    n=NR-1
    for (i=1; i<=NF; i++)
        mean[i]=sum[i]/n
}
{
    for (i=1; i<=NF; i++)
        sum2[i]+=($i-mean[i])*($i-mean[i])
}
END {
    for(i=1; i<=NF; i++)
        print sqrt(sum2[i]/n)
}' infile infile > outfile

, который менее эффективен, поскольку он читает данные дважды.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...