首页 文章

用awk计算平均值和标准差

提问于
浏览
16

我有一个'file.dat',包含24(行)x 16(列)数据 .

我已经测试了以下awk脚本来计算每列的平均值 .

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

它会在第二列中写入值,但它们不是标准差的正确值 . 偏差的计算不正确 . 我非常感谢任何帮助 . 问候

4 回答

  • 4

    标准差是

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

    但是这个公式的另一种形式并不需要你事先知道它的意思 . 它是:

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

    (对于标准差的“平方和”公式的快速网络搜索,如果您感兴趣,将为您提供推导)

    要使用此公式,您需要跟踪值的平方和和 . 所以你的awk脚本将改为:

    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
    
  • 28

    要计算数字列表的标准差,您可以使用如下命令:

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

    ^ 在POSIX中 . gawknawk 支持 ** ,但 mawk 不支持 ** .

  • -1

    这是我在研磨机数据输出文件上进行的一些计算,用于长时间浸泡测试,必须中断:

    Standard deviation(biased) + average:

    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) )}'
    

    Standard deviation(non-biased) + average:

    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)))}'
    
  • 9

    你的脚本应该以某种方式使用这种形式:

    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
    

相关问题