リストから最も代表的な値を選択してください。

リストから最も代表的な値を選択してください。

以下の(数千または数百万)の値のリストがあります。

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 | sortします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構成です。その後、繰り返して発生回数を合計し、終了条件が一致するまで高周波ペアを印刷します。awkcount

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

おすすめ記事