繁体   English   中英

在第二列中查找第一列中选​​择的平均值和最大值

[英]Find mean and maximum in 2nd column for a selection in 1st column

我有两列如下

ifile.dat
1   10
3   34
1   4
3   32
5   3
2   2
4   20
3   13
4   50
1   40
2   20
5   2

我想计算第一列中某些选择的第二列中的平均值和最大值。

ofile.dat
1-2   40  15.2 #Here 1-2 means all values in 1st column ranging from 1 to 2; 
               #40 is the maximum of corresponding values in 2nd column and 15.2 is their mean i.e. (10+4+2+40+20)/5
3-4   50  29.8 #Here 3-4 means all values in 1st column ranging from 3 to 4; 
               #50 is their maximum and 29.8 is their mean i.e. (34+32+20+13+50)/5
5-6   3    2.5 #Here 5-6 means all values in 1st column ranging from 5 to 6; 
               #3 is their maximum and 2.5 is their mean i.e. (3+2)/2

同样,如果我选择了 3 个数字的选择范围,那么期望的输出将是

ofile.dat
1-3 40 19.37
4-6 50 18.7

我有以下脚本计算第一列中的单个值。 但我正在寻找第一列中的多个选择。

awk '{
    if (a[$1] < $2) { a[$1]=$2 }} END { for (i in a){}} 
    {b[$1]+=$2; c[$1]++} END{for (i in b) 
    printf "%d %2s %5s  %5.2f\n", i, OFS, a[i], b[i]/c[i]}' ifile.dat

原始数据的第一列中的值从 1 到 100000 不等。所以我需要以 1000 的间隔进行分层。即 1-1000、1001-2000、2001-3000、...

以下 awk 脚本将提供带有分组的基本描述性统计信息。

建议研究更强大的解决方案(Python、Perl、R 等),这些解决方案将支持额外的措施、灵活性——没有必要重新发明这个圈子。

根据上面的评论,分组分隔的逻辑是 1-1000、1001-2000。 为了清楚起见,代码很冗长。

awk '
{
    # Total Counter
    nn++ ;

    # Group id
    gsize = 1000
    gid = int(($1-1)/gsize )

    v = $2
    # Setup new group, if needed
    if ( !n[gid] ) {
        n[gid] = 0
        sum[gid] = 0
        max[gid] = min[gid] = v 
        name[gid] = (gid*gsize +1) "-" ((gid+1)*gsize) 
    }
    if ( v > max[gid] ) max[gid] = v
    sum[gid] += v
    n[gid]++
}
END {
    # Print all groups
    for (gid in name) {
        printf "%-20s %4d %6.1f %5.1F\n", name[gid], max[gid], sum[gid]/n[gid], n[gid]/nn ;
    }
}
'

您能否尝试仅使用显示的示例进行跟踪、测试和编写。

sort -k1 Input_file |
awk -v range="1" '
  !b[$1]++{
    c[++count]=$1
  }
  {
    a[$1]=a[$1]>$2?a[$2]:$2
    d[$1]+=$2
    e[$1]++
    till=$1
  }
  END{
    for(i=1;i<=till;i+=(range+1)){
       for(j=i;j<=i+range;j++){
          max=max>a[c[j]]?max:a[c[j]]
          total+=d[c[j]]
          occr+=e[c[j]]
       }
       print i"-"i+range,max,occr?total/occr:0
       occr=total=max=""
    }
  }
'

对于显示的示例,输出如下。

1-2 40 15.2
3-4 50 29.8
5-6 3 2.5

我将range变量保持为1因为第一个数字的差异是2所以在您的情况下,可以说1,1001等等,然后将范围变量值保持为999

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM