如何从第n列的csv文件中计算行的平均值?
How to calculate the mean of row from csv file from nth column?
这可能看起来像重复的,但我无法解决我遇到的问题。
我正在尝试从 CSV/TSV 文件中找出每一列的平均值,数据如下所示:
input.tsv
ID source random text val1 val2 val3 val4 val330
1 atttt eeeee test 0.9 0.5 0.2 0.54 0.89
2 afdg adfgrg tf 0.6 0.23 0.5 0.4 0.29
output.tsv
ID source random text Avg
1 atttt eeeee test 0.606
2 afdg adfgrg tf 0.404
或至少
ID Avg
1 0.606
2 0.404
我尝试了 here
的建议
awk 'NR==1{next}
{printf("%s\t",
printf("%.2f\n", ( + + )/3}' input.tsv
抛出错误。
和
awk '{ s = 4; for (i = 5; i <= NF; i++) s += $i; print , (NF > 1) ? s / (NF - 1) : 0; }' input.tsv
下面的代码也抛出了语法错误
for i in `cat input.tsv` do; VALUES=`echo $i | tr '\t' '\t'`;COUNT=0;SUM=0;typeset -i j;IFS=' ';for j in $VALUES; do;SUM=`expr $SUM + $j`;COUNT=`expr $COUNT + 1`;done;AVG=`expr $SUM / $COUNT`;echo $AVG;done
帮我解决计算行平均值的问题
您可以使用这个 awk
脚本:
awk 'NR>1{
for(i=5;i<=NF;i++)
sum+=$i
}
{
print ,,,,(NF>4&&sum!=""?sum/(NF-4):(NR==1?"Avg":""))
sum=0
}' file | column -t
第一个块获取从第 5 个元素开始的所有 id 的总和。
第二块,打印header行和平均值。
column -t
显示列中的结果。
这将按预期工作:
awk 'BEGIN{OFS="\t"}
(NR==1){ print ,,,,"Avg:"; next }
{ s=0; for(i=5;i<=NF;++i) s+=$i }
{ print ,,,, (NF>4 ? s/(NF-4) : s) }' input.tsv
或者只是为了好玩,如果你想混淆 for 循环:
awk 'BEGIN{OFS="\t"}
(NR==1){ print ,,,,"Avg:"; next }
{ for(s=!(i=5);i<=NF;s+=$(i++)) {} }
{ print ,,,, (NF>4 ? s/(NF-4) : s) }' input.tsv
来自您的代码参考:
awk 'NR==1{next}
{
# missing the last ). This print the 1st column
#printf("%s\t",
printf("%s\t", )
# missing the last ) and average of 3 colum only
#printf("%.2f\n", ( + + )/3
printf("%.2f\n", ( + + + + ) / 5 )
}' input.tsv
你的第二个代码不容易处理,很多子shell(反向)和shell循环,但最重要的是,我认为它是为处理整数值和完整的价值线(不是 5-> 9)。算了吧,除非你不想在这种情况下使用 awk。
为了好玩
awk 'NR==1{
# Header
print [=11=] OFS "Avg"
Count = NF - 5
next
}
{
# print each element of the line + sum after col 4
for( i=Avg=0;i<=NF;i++) {
if( i >=5 ) Avg+= $i
printf( "%s ", $i)
}
# print average
printf( "%.2f\n", Avg/Count )
}
' input.tsv
这里假设它总是对完整堆栈的值进行计数,我们可以将计数更改为(NF - 4)
如果线上的值较少且空的不在计数
$ cat tst.awk
NR == 1 { avg = "Avg" }
NR > 1 {
sum = cnt = 0
for (i=5; i<=NF; i++) {
sum += $i
cnt++
}
avg = (cnt ? sum / cnt : 0)
}
{ print , , , , avg }
$ awk -f tst.awk file
ID source random text Avg
1 atttt eeeee test 0.606
2 afdg adfgrg tf 0.404
使用 Perl 一行代码
> perl -lane '{ $s=0;foreach(@F[4..8]){$s+=$_} $F[4]=$s==0?"Avg":$s/5;print "$F[0]\t$F[1]\t$F[2]\t$F[3]\t$F[4]" } ' input.tsv
ID source random text Avg
1 atttt eeeee test 0.606
2 afdg adfgrg tf 0.404
>
这可能看起来像重复的,但我无法解决我遇到的问题。
我正在尝试从 CSV/TSV 文件中找出每一列的平均值,数据如下所示:
input.tsv
ID source random text val1 val2 val3 val4 val330
1 atttt eeeee test 0.9 0.5 0.2 0.54 0.89
2 afdg adfgrg tf 0.6 0.23 0.5 0.4 0.29
output.tsv
ID source random text Avg
1 atttt eeeee test 0.606
2 afdg adfgrg tf 0.404
或至少
ID Avg
1 0.606
2 0.404
我尝试了 here
的建议awk 'NR==1{next}
{printf("%s\t",
printf("%.2f\n", ( + + )/3}' input.tsv
抛出错误。
和
awk '{ s = 4; for (i = 5; i <= NF; i++) s += $i; print , (NF > 1) ? s / (NF - 1) : 0; }' input.tsv
下面的代码也抛出了语法错误
for i in `cat input.tsv` do; VALUES=`echo $i | tr '\t' '\t'`;COUNT=0;SUM=0;typeset -i j;IFS=' ';for j in $VALUES; do;SUM=`expr $SUM + $j`;COUNT=`expr $COUNT + 1`;done;AVG=`expr $SUM / $COUNT`;echo $AVG;done
帮我解决计算行平均值的问题
您可以使用这个 awk
脚本:
awk 'NR>1{
for(i=5;i<=NF;i++)
sum+=$i
}
{
print ,,,,(NF>4&&sum!=""?sum/(NF-4):(NR==1?"Avg":""))
sum=0
}' file | column -t
第一个块获取从第 5 个元素开始的所有 id 的总和。
第二块,打印header行和平均值。
column -t
显示列中的结果。
这将按预期工作:
awk 'BEGIN{OFS="\t"}
(NR==1){ print ,,,,"Avg:"; next }
{ s=0; for(i=5;i<=NF;++i) s+=$i }
{ print ,,,, (NF>4 ? s/(NF-4) : s) }' input.tsv
或者只是为了好玩,如果你想混淆 for 循环:
awk 'BEGIN{OFS="\t"}
(NR==1){ print ,,,,"Avg:"; next }
{ for(s=!(i=5);i<=NF;s+=$(i++)) {} }
{ print ,,,, (NF>4 ? s/(NF-4) : s) }' input.tsv
来自您的代码参考:
awk 'NR==1{next}
{
# missing the last ). This print the 1st column
#printf("%s\t",
printf("%s\t", )
# missing the last ) and average of 3 colum only
#printf("%.2f\n", ( + + )/3
printf("%.2f\n", ( + + + + ) / 5 )
}' input.tsv
你的第二个代码不容易处理,很多子shell(反向)和shell循环,但最重要的是,我认为它是为处理整数值和完整的价值线(不是 5-> 9)。算了吧,除非你不想在这种情况下使用 awk。
为了好玩
awk 'NR==1{
# Header
print [=11=] OFS "Avg"
Count = NF - 5
next
}
{
# print each element of the line + sum after col 4
for( i=Avg=0;i<=NF;i++) {
if( i >=5 ) Avg+= $i
printf( "%s ", $i)
}
# print average
printf( "%.2f\n", Avg/Count )
}
' input.tsv
这里假设它总是对完整堆栈的值进行计数,我们可以将计数更改为(NF - 4)
如果线上的值较少且空的不在计数
$ cat tst.awk
NR == 1 { avg = "Avg" }
NR > 1 {
sum = cnt = 0
for (i=5; i<=NF; i++) {
sum += $i
cnt++
}
avg = (cnt ? sum / cnt : 0)
}
{ print , , , , avg }
$ awk -f tst.awk file
ID source random text Avg
1 atttt eeeee test 0.606
2 afdg adfgrg tf 0.404
使用 Perl 一行代码
> perl -lane '{ $s=0;foreach(@F[4..8]){$s+=$_} $F[4]=$s==0?"Avg":$s/5;print "$F[0]\t$F[1]\t$F[2]\t$F[3]\t$F[4]" } ' input.tsv
ID source random text Avg
1 atttt eeeee test 0.606
2 afdg adfgrg tf 0.404
>