如果特定字段的行匹配,部分记录上的awk差异

如果特定字段的行匹配,部分记录上的awk差异,awk,Awk,我对使用awk非常陌生,但是我在Fredrik Pihl对这个问题的回答中发现了很多帮助,关于如何计算一个字段($3)相对于共享另一个字段($1)的许多记录的平均值: 问题:如果行(特定字段)匹配,awk列的平均部分 输入样本: $cat NDVI-bm P01 031.RAW 0.516 0 0 P01 021.RAW 0.449 0 0 P02 045.RAW 0.418 0 0 P03 062.RAW 0.570 0 0 P03 064.RAW 0.469 0 0

我对使用awk非常陌生,但是我在Fredrik Pihl对这个问题的回答中发现了很多帮助,关于如何计算一个字段($3)相对于共享另一个字段($1)的许多记录的平均值:

问题:如果行(特定字段)匹配,awk列的平均部分

输入样本:

$cat NDVI-bm  
P01 031.RAW 0.516 0 0  
P01 021.RAW 0.449 0 0  
P02 045.RAW 0.418 0 0  
P03 062.RAW 0.570 0 0  
P03 064.RAW 0.469 0 0  
P04 083.RAW 0.636 0 0  
P04 081.RAW 0.592 0 0  
P04 082.RAW 0.605 0 0  
P04 084.RAW 0.648 0 0  
P05 093.RAW 0.748 0 0
弗雷德里克·皮尔的回答:

{
    sum[$1]+=$3
    cnt[$1]++
}


END {
    print "Name" "\t" "sum" "\t" "cnt" "\t" "avg"
    for (i in sum)
        print i "\t" sum[i] "\t" cnt[i] "\t" sum[i]/cnt[i]

}

但是,我也在尝试计算匹配字段的方差(每个值和平均值之间的差值平方和除以计数)时遇到了困难。我想我可能需要一种方法来计算每个匹配记录在结束结构之前的平均值,或者如果可以在结束结构内进行整个方差计算,但我需要以某种方式检索原始值$3。我也不知道该怎么做。谢谢你的提示。

你可以通过计算样本的平方和和来计算最后的方差

然后

所以

要选择特定模式,请将其添加到求和计算的开始(注意,结束与文件的结束匹配),例如

现在,只有其中包含P03的行将被处理

GNU代码:


$cat文件 P01 031.0.516 0 0 0 P01 021.0.449 0 0 0 P02 045.0.418 0 0 P03062.0.570 0 P03064.0.469.0 P04083.0.636 0 0 P04081.0.592.0 P04 082.0.605 0 0 P04 084.0.648 0 0 0 P05 093.0.748 0 0 0 $awk-f prog.awk文件 组:P01计数:2平均值:0.4825和:0.965 sumdiff^2:0.0022445方差:0.00112225 组:P02计数:1平均值:0.418总和:0.418总和差异^2:0方差:0 组:P03计数:2平均值:0.5195和:1.039 sumdiff^2:0.0051005方差:0.0025025 组:P04计数:4平均值:0.62025总和:2.481 sumdiff^2:0.00204875方差:0.000512188 组:P05计数:1平均值:0.748和:0.748 sumdiff^2:0方差:0
我认为在你的awk脚本中, 组[$3]=$1
如果第3列中有多个RAW具有相同的值,则无法正常工作,因为这N个相同的值在组中只计算一次。

如果您发布了所需的输出,如果您捐赠了可能会有帮助的赏金,则会有帮助。@JS웃 帕克德:谢谢。@captcha:什么意思?
variance = (Sum of squares - (Sum*Sum)/n)/n
{
    sum[$1]+=$3
    sum_squares[$1]+=$3*$3
    cnt[$1]++
}


END {
    print "Name" "\t" "sum" "\t" "cnt" "\t" "avg" "\t" "var"
    for (i in sum)
        print i "\t" sum[i] "\t" cnt[i] "\t" sum[i]/cnt[i] "\t" (sum_squares[i] - (sum[i]*sum[i])/cnt[i])/cnt[i]

}
/P03/ {
    sum[$1]+=$3
    sum_squares[$1]+=$3*$3
    cnt[$1]++
}
{
    sum[$1]+=$3
    count[$1]++
    groups[$3]=$1
}

END {
    for (i in sum) mean[i]=sum[i]/count[i]
    for (i in groups) meandiff[i]=i-mean[groups[i]]
    for (i in groups) sumdiff2[groups[i]]+=meandiff[i]^2
    for (i in sumdiff2) var[i]=sumdiff2[i]/count[i]
    for (i in var)
        print "group:", i, "count:", count[i], "\tmean:", mean[i], "\tsum:", sum[i], "\tsumdiff^2:", sumdiff2[i], "\t\tvariance:", var[i]
}
$cat file P01 031.RAW 0.516 0 0 P01 021.RAW 0.449 0 0 P02 045.RAW 0.418 0 0 P03 062.RAW 0.570 0 0 P03 064.RAW 0.469 0 0 P04 083.RAW 0.636 0 0 P04 081.RAW 0.592 0 0 P04 082.RAW 0.605 0 0 P04 084.RAW 0.648 0 0 P05 093.RAW 0.748 0 0 $awk -f prog.awk file group: P01 count: 2 mean: 0.4825 sum: 0.965 sumdiff^2: 0.0022445 variance: 0.00112225 group: P02 count: 1 mean: 0.418 sum: 0.418 sumdiff^2: 0 variance: 0 group: P03 count: 2 mean: 0.5195 sum: 1.039 sumdiff^2: 0.0051005 variance: 0.00255025 group: P04 count: 4 mean: 0.62025 sum: 2.481 sumdiff^2: 0.00204875 variance: 0.000512188 group: P05 count: 1 mean: 0.748 sum: 0.748 sumdiff^2: 0 variance: 0