计算每个变量的百分位数和最大值

Compute percentile and max value per variable

Bash 大师们,我需要使用 awk

计算列表中每个项目的最大值和百分位数
aa  1
ab  3
aa  4
ac  5
aa  3
ad  2
ab  4
ac  2
ae  2
ac  5

预期输出

Item   90th percentile   max value
aa     3.8             4
ab     3.9             4
ac     5               5
ad     2               2
ae     2               2

我能够使用下面的方法得到总和和最大值,但不能得到百分位数。

awk '{
item[]++;
count[]+=;
max[]=;
percentile[,.9]=
 }
 END{
 for (var in item)
 print var,count[var],max[var],percentile[var]
 }
' 

求推荐。

百分位数计算来自 Statistics for Dummies 第 2 版。 :).在 Gnu awk 中:

$ cat mnp.awk
BEGIN {
    PROCINFO["sorted_in"]="@ind_num_asc"   # for order in output
    if(p=="")                              # if p not defined it's median
        p=0.5
    else
        p=p/100                            # if 90th percentile: p=0.9
}
{
    v[][NR]=                           # values stored per keyword. NR for unique
    if(>m[])                           # find max val
        m[]=
}
END {
    for(i in v) {                          # for all keywords
        n=asort(v[i])                      # sort values, n is count
        prc=p*n;                           # percentile figuration
        if(prc==int(prc))
            w=(v[i][prc]+v[i][prc+1])/2
        else
            w=v[i][int(prc)+1]
        print i, m[i], w                   # print keyword, max and nth value
    }
}

运行它:

$ awk -p=90 -f mnp.awk data.txt
aa 4 4
ab 4 4
ac 5 5
ad 2 2
ae 2 2

TODO:如果数据文件已排序,这可以简化,并不是所有数据都需要存储到内存中。

这是我在互联网上找到的一个优雅的解决方案,用于查找最大值:

{
  max[] = !( in max) ?  : ( > max[]) ?  : max[]
}
END {
  for (i in max)
    print i, max[i]
}

输出:

ab 4
ac 5
ad 2
ae 2
aa 4

datamash 是一个可爱的工具,虽然它不支持 percantile 部分。

$ datamash -W --sort --group=1 max 2 min 2 < INPUT
aa  4   1
ab  4   3
ac  5   2
ad  2   2
ae  2   2

支持以下操作

File operations:
  transpose, reverse
Numeric Grouping operations:
  sum, min, max, absmin, absmax
Textual/Numeric Grouping operations:
  count, first, last, rand 
  unique, collapse, countunique
Statistical Grouping operations:
  mean, median, q1, q3, iqr, mode, antimode
  pstdev, sstdev, pvar, svar, mad, madraw
  pskew, sskew, pkurt, skurt, dpo, jarque