有没有办法根据另一个字段中的变量获取一个字段中的平均值?例如对于以下输入
a x 3
b y 4
a y 2
b x 5
b x 20
我想要这个输出
a 2.5
b 9.67
我发现这个 awk 脚本可以获取列中值的平均值
awk '{ total += $3; count++ } END { print total/count }' file.txt
但如何在其中添加 for 循环以获得第一列中每个变量的平均值?
该文件以制表符分隔。
谢谢
答案1
你离这个还不算太远。尝试按以下索引的数组$1
:
awk '{ total[$1] += $3; count[$1]++ } END {for (t in total) print t, total[t]/count[t]}' file
a 2.5
b 9.66667
或者,如果您想要最多两位小数,如您在问题中所示:
$ awk '{ total[$1] += $3; count[$1]++ } END {for (t in total) printf "%s %.2f\n", t, total[t]/count[t]}' file
a 2.50
b 9.67
答案2
使用 GNU datamash
:
$ datamash -R2 -W -s -g 1 mean 3 <file
a 2.50
b 9.67
$ datamash -W -s -g 1 mean 3 <file
a 2.5
b 9.6666666666667
-R2
四舍五入到小数点后两位-W
使用空格和/或制表符作为字段分隔符-s
分组前先排序-g 1
第一个字段上的组mean 3
值的平均值,第三个字段
如果您想在输出中用空格字符替换制表符,则可以删除-W
制表符作为分隔符添加的内容。--output-delimiter=' '
答案3
磨坊主对于像这样的任务也很方便。
$ mlr --nidx stats1 -a mean -f 3 -g 1 file.txt
a 2.500000
b 9.666667
或(带有动词的更新版本format-values
)
$ mlr --nidx stats1 -a mean -f 3 -g 1 then format-values -f '%.2f' file.txt
a 2.50
b 9.67
答案4
#!/bin/bash
counta=`awk '$1 ~ /^a$/{print NR}' filename| awk 'END{print NR}'`
countb=`awk '$1 ~ /^b$/{print NR}' filename| awk 'END{print NR}'`
awk -v counta="$counta" '{if ($1 == "a"){sum=sum+$NF}}END{print "a" " " sum/counta}' filename
awk -v countb="$countb" '{if ($1 == "b"){sum=sum+$NF}}END{print "b" " " sum/countb}' filename
输出
a 2.5
b 9.66667