Подтвердить что ты не робот

Вычислить среднее и стандартное отклонение с помощью awk

У меня есть файл file.dat с 24 (строками) x 16 (столбцами) данных.

Я уже протестировал следующий awk script, который вычисляет среднее значение для каждого столбца.

touch aver-std.dat
awk '{   for (i=1; i<=NF; i++) { sum[i]+= $i } }
END { for (i=1; i<=NF; i++ )  
{ printf "%f \n", sum[i]/NR} }' file.dat >> aver-std.dat

На выходе 'aver-std.dat' имеется один столбец с этими средними значениями.

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

Я делал разные тесты, как этот

touch aver-std.dat
awk '{   for (i=1; i<=NF; i++) { sum[i]+= $i }}
END { for (i=1; i<=NF; i++ )  
{std[i] += ($i - sum[i])^2 ; printf "%f %f \n", sum[i]/NR, sqrt(std[i]/(NR-1))}}' file.dat >> aver-std.dat

и он записывает значения во втором столбце, но они не являются правильным значением стандартного отклонения. Вычисление отклонения некорректно. Я был бы очень признателен за любую помощь. Отношения

4b9b3361

Ответ 1

Стандартное отклонение

stdev = sqrt((1/N)*(sum of (value - mean)^2))

Но есть другая форма формулы, которая не требует, чтобы вы знали среднее значение заранее. Это:

stdev = sqrt((1/N)*((sum of squares) - (((sum)^2)/N)))

(Быстрый веб-поиск формулы "сумма квадратов" для стандартного отклонения даст вам вывод, если вы заинтересованы)

Чтобы использовать эту формулу, вам нужно отслеживать как сумму, так и сумму квадратов значений. Таким образом, ваш awk script изменится на:

    awk '{for(i=1;i<=NF;i++) {sum[i] += $i; sumsq[i] += ($i)^2}} 
          END {for (i=1;i<=NF;i++) {
          printf "%f %f \n", sum[i]/NR, sqrt((sumsq[i]-sum[i]^2/NR)/NR)}
         }' file.dat >> aver-std.dat

Ответ 2

Чтобы просто рассчитать стандартное отклонение численности списка чисел, вы можете использовать такую команду:

awk '{x+=$0;y+=$0^2}END{print sqrt(y/NR-(x/NR)^2)}'

Или это вычисляет стандартное отклонение образца:

awk '{sum+=$0;a[NR]=$0}END{for(i in a)y+=(a[i]-(sum/NR))^2;print sqrt(y/(NR-1))}'

^ находится в POSIX. ** поддерживается gawk и nawk но не mawk.

Ответ 3

Вот несколько расчетов, которые я сделал в файле вывода данных шлифовального станка для длительного теста на выдержку, который должен был быть прерван:

Стандартное отклонение (смещенное) + среднее:

cat <grinder_data_file> | grep -v "1$" | awk -F ', '  '{   sum=sum+$5 ; sumX2+=(($5)^2)} END { printf "Average: %f. Standard Deviation: %f \n", sum/NR, sqrt(sumX2/(NR) - ((sum/NR)^2) )}'

Стандартное отклонение (без смещения) + среднее:

cat <grinder_data_file>  | grep -v "1$" | awk -F ', '  '{   sum=sum+$5 ; sumX2+=(($5)^2)} END { avg=sum/NR; printf "Average: %f. Standard Deviation: %f \n", avg, sqrt(sumX2/(NR-1) - 2*avg*(sum/(NR-1)) + ((NR*(avg^2))/(NR-1)))}'

Ответ 4

Ваш script должен как-то быть в этой форме:

awk '{
    sum = 0
    for (i=1; i<=NF; i++) {
        sum += $i
    }
    avg = sum / NF
    avga[NR] = avg
    sum = 0
    for (i=1; i<=NF; i++) {
        sum += ($i - avg) ^ 2
    }
    stda[NR] = sqrt(sum / NF)
}

END { for (i = 1; i in stda; ++i) { printf "%f %f \n", avga[i], stda[i] } }' file.dat >> aver-std.dat