选择列表中代表性最高的值

选择列表中代表性最高的值

我有一个(数百个或数百万个)值的列表,例如:

echo -e "y\ny\ny\nu\ni\no\no\nl\no\nj\nk\nl\nk\nl\nk\nl\nk\nl\nk\nl\no\nu\no\no\nu\ny\nl\ni\nq\nw\ne\nr\nt\na\ns" > list.txt

我想计算每个值在列表中出现的次数,然后选择代表列表中条目的任意部分的最常见值 ( keep)。我不在乎打破我的实际数据集中的联系。

我当前的工作代码使用sort | uniq | sortand awk

keep=0.50
sort list.txt | uniq -c | sort -nr > temp
awk -v keep=$keep 'NR==FNR {s+=$1}; NR!=FNR {c+=$1; print $0}; c > (s * keep) {exit 0}' temp temp
      7 l
      6 o
      5 k

然而,这两段代码看起来都非常笨拙。有一个更好的方法吗?我无法找到正确的搜索词(因此这个问题的标题很糟糕)。

答案1

您可以使用单个awk命令(GNU 版本)根据数组包含的值对数组进行唯一排序。是count一个关联数组,它唯一地计算文件中每一行的出现次数。

PROCINFO["sorted_in"] = "@val_type_desc"是一个 GNU构造,它按值的降序对awk数组中的条目进行排序。count然后,您对其进行迭代以对出现次数进行求和并打印高频对,直到匹配退出条件。

awk -v keep=0.50 '
{
    count[$0]++
}

END {
    PROCINFO["sorted_in"] = "@val_type_desc"
    for (i in count) {
        sum += count[i]
        print i, count[i]
        if (sum > (NR * keep)) {
            break
        }
    }
}' list.txt

相关内容