需要使用 bash 和 awk 计算数组的标准差吗?

Need to calculate standard deviation from an array using bash and awk?

伙计们,我是 awk 的新手,我正在努力使用 awk 命令来查找标准偏差。

我使用以下方法得到了平均值:

echo ${GfieldList[@]} | awk 'NF {sum=0;for (i=1;i<=NF;i++)sum+=$i; print "Mean= " sum / NF; }'

标准差公式为:

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

我用上面的公式找到了平均值

你们能帮我解决这个问题的 awk 命令吗?

一旦你知道了平均值:

awk '{
    for (i = 1;i <= NF; i++) {
        sum += $i
    };
    print sum / NF
}' # for 2, 4, 4, 4, 5, 5, 7, 9 gives 5

那么标准差可以这样求:

awk -vM=5 '{
    for (i = 1; i <= NF; i++) {
        sum += ($i-M) * ($i-M)
    };
    print sqrt (sum / NF)
}' # for 2, 4, 4, 4, 5, 5, 7, 9 gives 2

在"compressed"形式中:

awk '{for(i=1;i<=NF;i++){sum+=$i};print sum/NF}'
awk -vM=5 '{for(i=1;i<=NF;i++){sum+=($i-M)*($i-M)};print sqrt(sum/NF)}'

(将 M 的值更改为从第一个命令中提取的实际平均值)。

standard deviation 的另一个公式是数量的平方根:(均方减去均值的平方)。这是在下面使用的:

$ echo 20 21 22 | awk 'NF {sum=0;ssq=0;for (i=1;i<=NF;i++){sum+=$i;ssq+=$i**2}; print "Std Dev=" (ssq/NF-(sum/NF)**2)**0.5}'
Std Dev=0.816497

备注:

  • awk中,NF是一行中"fields"的个数。在我们的例子中,每个字段都是一个数字,所以 NF 是给定行上的数字数。

  • ssq是直线上每个数的平方和。因此,ssq/NF 是均方。

  • sum是线上数字的总和。因此 sum/NF 是平均值,(sum/NF)**2 是平均值的平方。

  • 根据公式,则标准差为(ssq/NF-(sum/NF)**2)**0.5.

awk代码

  • NF

    这是一个条件:只有当这一行的字段数 NF 的计算结果为真(即非零)时,才会执行后面的语句。也就是说,这种情况会导致空行被跳过。

  • sum=0;ssq=0;

    这会将 sumssq 初始化为零。仅当输入多于一行时才需要。

  • for (i=1;i<=NF;i++){sum+=$i;ssq+=$i**2}

    这会将sum中所有数字的总和与ssq中数字的平方和相加。

  • print "Std Dev=" (ssq/NF-(sum/NF)**2)**0.5

    这会打印出标准偏差。