如何使用awk计算一天内重复记录的平均值?

如何使用awk计算一天内重复记录的平均值?,awk,Awk,有谁能告诉我如何使用awk计算每天($2)重复记录的平均值,使用数据集的唯一id($1)和测量($3)记录。 数据集如下所示: 32070 2010-12-15 540 32070 2010-12-15 546 32070 2010-12-15 549 32070 2010-12-17 579 32070 2010-12-17 553 25903 2010-12-15 556 25903

有谁能告诉我如何使用awk计算每天($2)重复记录的平均值,使用数据集的唯一id($1)和测量($3)记录。 数据集如下所示:

32070     2010-12-15    540  
32070     2010-12-15    546  
32070     2010-12-15    549  
32070     2010-12-17    579  
32070     2010-12-17    553  
25903     2010-12-15    556  
25903     2010-12-15    543  
25903     2010-12-15    564  
25903     2010-12-16    567  
25903     2010-12-16    583 
我希望根据每个唯一ID($1)的测量($3)获得每天记录($2)的平均值,并单独打印输出文件,如下所示:

32070  2010-12-15    545  
32070  2010-12-17    566  
25903  2010-12-15     554.33  
25903  2010-12-16     575  
输出

解释

subsp
是一个内部变量,用于在中分隔键。其默认值为
“\034”
,不太可能出现在输入中。出于调试目的,我已将其设置为
@
。您可以跳过修改此变量

与“预期输出”相比,输出的顺序将不同。但您可以使用
sort
工具按列轻松排序。例如,以下内容将按第二列对输出进行排序,然后按第一列(按顺序)对输出进行排序:

输出

这只是一个样本。你应该知道大概的意思。根据需要修改命令

$ cat tst.awk
{ curr = $1 OFS $2 }
curr != prev { if (cnt) print prev, sum / cnt; sum=cnt=0 }
{ sum+=$3; cnt++; prev=curr }
END { if (cnt) print prev, sum / cnt }

$ awk -f tst.awk file
32070 2010-12-15 545
32070 2010-12-17 566
25903 2010-12-15 554.333
25903 2010-12-16 575
输出

解释

subsp
是一个内部变量,用于在中分隔键。其默认值为
“\034”
,不太可能出现在输入中。出于调试目的,我已将其设置为
@
。您可以跳过修改此变量

与“预期输出”相比,输出的顺序将不同。但您可以使用
sort
工具按列轻松排序。例如,以下内容将按第二列对输出进行排序,然后按第一列(按顺序)对输出进行排序:

输出

这只是一个样本。你应该知道大概的意思。根据需要修改命令

$ cat tst.awk
{ curr = $1 OFS $2 }
curr != prev { if (cnt) print prev, sum / cnt; sum=cnt=0 }
{ sum+=$3; cnt++; prev=curr }
END { if (cnt) print prev, sum / cnt }

$ awk -f tst.awk file
32070 2010-12-15 545
32070 2010-12-17 566
25903 2010-12-15 554.333
25903 2010-12-16 575
此答案与@Ruslans答案的区别在于:

  • His将整个输入文件存储在内存中,而上面只将4个变量(curr、prev、sum和cnt)的值存储在内存中
  • His以随机(实际上在大多数awk实现中是散列)顺序输出结果,而上面的输出结果以它们在输入中出现的顺序输出
  • 无论您的输入以何种顺序出现,His都将起作用,而上述内容取决于您的输入是否按id和日期排序
  • 此答案与@Ruslans答案的区别在于:

  • His将整个输入文件存储在内存中,而上面只将4个变量(curr、prev、sum和cnt)的值存储在内存中
  • His以随机(实际上在大多数awk实现中是散列)顺序输出结果,而上面的输出结果以它们在输入中出现的顺序输出
  • 无论您的输入以何种顺序出现,His都将起作用,而上述内容取决于您的输入是否按id和日期排序

  • 如果您想将subsp设置为某个值,请将其设置为OFS,这样您就不需要结尾部分中的
    split()
    部分数组,您只需按原样打印
    x
    索引,同时去掉硬编码的
    ,而使用正常的
    输出分隔符。@EdMorton,谢谢。我只是想向他展示一下大概的想法。我发现你的建议很有用,我认为OP也会发现它们很有用。如果你想将subsp设置为某个值,请将其设置为OFS,这样你就不需要
    split()
    和结尾部分的
    部分
    数组,你只需按原样打印
    x
    索引,同时去掉硬编码的
    “”
    为了支持正常的
    输出分隔符。@EdMorton,谢谢。我只是想向他展示一下大概的想法。我觉得你的建议很有用,而且我认为OP也会发现它们很有用。剧本只是照原样给我,不需要平均每日记录。我期待你的答复。感谢您在复制/粘贴时出错,或者您的输入与您提供的示例不符。正如您在我的回答中所看到的,脚本确实按照您提供的示例输入所要求的做了。脚本只按原样给我,而不求每日记录的平均值。我期待你的答复。感谢您在复制/粘贴时出错,或者您的输入与您提供的示例不符。正如您在我的回答中所看到的,给定您提供的示例输入,脚本会按照您的要求执行。
    awk -f script.awk file | sort -k2 -k1g
    
    25903 2010-12-15 554.333
    25903 2010-12-16 575
    32070 2010-12-15 545
    32070 2010-12-17 566
    
    $ cat tst.awk
    { curr = $1 OFS $2 }
    curr != prev { if (cnt) print prev, sum / cnt; sum=cnt=0 }
    { sum+=$3; cnt++; prev=curr }
    END { if (cnt) print prev, sum / cnt }
    
    $ awk -f tst.awk file
    32070 2010-12-15 545
    32070 2010-12-17 566
    25903 2010-12-15 554.333
    25903 2010-12-16 575