仅考虑高于某个值的值来获取列的平均值

时间:2021-07-14 09:32:07

标签: awk

我正在计算文件第三列的平均值和标准偏差。现在,在不修改此文件的情况下,我还想计算这些值,只考虑那些值高于 0 的行。

这是我正在使用的命令:

awk '{sum+=$3; sumsq+=$3*$3} END {print "MEAN:",sum/NR; print "SD:",sqrt(sumsq/NR - (sum/NR)**2)}' myFile > mean.txt

你知道我如何调整它以获得均值和标准差,但只考虑高于 0 的值,就好像这些行不存在一样。

这是我的文件的头部(并且在整个文件中没有数字小于 0):

A  g1  10
B  g6  5
C  h7  3
D  l8  0
F  gg  1
T  o7  0
O  m7  33

我想要的输出(想象这是我的整个文件)是:

MEAN: 7.428  SD: 10.939
MEAN1: 10.4 SD1: 11.68

谢谢!

2 个答案:

答案 0 :(得分:1)

你可以很容易地做到这一点。在 END 之前的规则中,您只需要保留值为零的行数的计数器。 skipped 下面。然后在 END 中计算更新的 nr = NR - skipped 并将其用于您的第二个 print,例如

awk '
    $3==0 { skipped++; next } 
          { sum+=$3; sumsq+=$3*$3 } 
    END   { nr = NR - skipped
            print "MEAN:",sum/NR "  SD:",sqrt(sumsq/NR - (sum/NR)**2)
            print "MEAN:",sum/nr "  SD:",sqrt(sumsq/nr - (sum/nr)**2)
           }
' myFile

示例使用/输出

您可以简单地在 myFile 位于当前目录中的 xterm 中复制/鼠标中键粘贴,例如:

$ awk '
>     $3==0 { skipped++; next }
>           { sum+=$3; sumsq+=$3*$3 }
>     END   { nr = NR - skipped
>             print "MEAN:",sum/NR "  SD:",sqrt(sumsq/NR - (sum/NR)**2)
>             print "MEAN:",sum/nr "  SD:",sqrt(sumsq/nr - (sum/nr)**2)
>            }
> ' myFile
MEAN: 7.42857  SD: 10.9395
MEAN: 10.4  SD: 11.6893

告诉我这是否满足您的需求,如果您有任何其他问题。

答案 1 :(得分:0)

我会按照以下方式使用 GNU AWK,为简单起见,我只会处理 mean,让 file.txt 内容为

A  g1  10
B  g6  5
C  h7  3
D  l8  0
F  gg  1
T  o7  0
O  m7  33

然后

awk '{sum+=$3}$3>0{sum1+=$3;cnt1+=1}END{print "MEAN:",sum/NR,"MEAN1:",sum1/cnt1}' file.txt

输出

MEAN: 7.42857 MEAN1: 10.4

说明:整个数据的求和计算保持不变。我添加了要在第 3 列 ($3) 大于 (>) 大于零 (0) 的情况下应用的操作,这确实使用了单独的变量 sum1 和变量 {{ 1}} 作为计数器。最后我cnt1计算了均值。

(在 gawk 4.2.1 中测试)