ファイル内の値の最初の5%を印刷します。

ファイル内の値の最初の5%を印刷します。

2番目の列の値の上位5%を印刷したいと思います。 Excelでもできますが、値の上位5%を新しいファイルとして印刷したいと思います。同様の質問を検索しましたが、最初の5つの値のみを印刷するように提案を見つけることができます。お時間をいただきありがとうございます。

ありがとう kp

file.txt

X1 h
382 15325,3
385 15446,4
386 16501,5
446 16480
460 16467,7
534 16437,2
762 16433,7
779 16400,6
783 16398
828 16376,4
918 16319,4

x2 H   
52214 3966,33
52291 3993,4
53165 3500,57
53684 3071,67
54902 2169,83
54921 1968,9
55457 1943,98
55458 903,539
55459 609,993
55460 621,414
55461 553,236
55470 535,005
55472 298,251
55473 298,251
55474 298,251
55475 302,34
55559 371,47
55614 466,165
55679 406,352
55735 426,36

X3 H 
191773 178,645
191775 183,613
191780 193,663
191820 202,933
191838 188,988
191845 175,414
191867 167,791
191880 166,49
191883 170,456
191895 165,781
191900 154,362
191902 177,768
191914 175,431
191916 168,532
191918 163,291
191919 170,911

予想生産量(上位5%)

386 16501,5
446 16480

答え1

1つの難しさは、ピリオドだけを小数点区切り記号として扱うことawkです。awk

質問に対するコメントで要求されたように、最も高い値の95%以上の値を報告するには、次のようにします。

awk '{v = $2; gsub(",", ".", v); v += 0}
     !second_pass {
        if (v >= max || !started) {max = v; started=1}
        next
     }
     v >= 95 * max / 100' file second_pass=1 file

これは作る:

386 16501,5
446 16480
460 16467,7
534 16437,2
762 16433,7
779 16400,6
783 16398
828 16376,4
918 16319,4

最も高い値を持つ上位5%の行が必要な場合は、これを使用すると思います。 (同様の値を含まない行を無視したいと予想されますX3 H。)perl

perl -lane 'if ($F[1] =~ /\d/) {push @v, ($F[1] =~ y/,/./r); push @l, $_}
            END {
              print for (map {$l[$_]}
                        sort {$v[$b] <=> $v[$a]}
                        (0..$#v))[0..($#v+1)*5/100-1]
            }' file

これは作る:

386 16501,5
446 16480

答え2

TxRはっきりしない言葉アッ別のコードで囲まれたマクロ:

(let* ((data (build
               (awk ((set rec (regsub #/,/ "." rec))
                     (fconv - r))
                 ([f 1] (add (list [f 1] orec))))))
       (n (length data)))
  (mapdo (opip second put-line)
         [[sort data > first] (trunc (* 5 0..n) 100)]))

伝説:let*buildawkrecorecfconvmapdoopip

ランニング:

$ txr top5.tl file.txt
386 16501,5
446 16480

これは、Awkの例がLispマクロの場合に他の構造に簡単に組み込むことができることを示しています。ここではbuild、リストが作成されるコンテキストを設定するフォーム内に表示されます。(add ...)内部マクロは、build実行が完了すると(内部操作が完了した場合)、返される非表示のリストに追加されます。(build ...)awk

私たちが作成したリストはペアリストです。各ペアの最初の要素は浮動小数点値です。 2番目の要素は文字列です。つまり、orec変数から取得した元の awk レコードの蓄積レコードです。データをソートするときは、各ペアの最初の要素をソートキーとして使用し、関数を介して降順を使用します>。ソートされたデータの最初の5%を印刷するときは、(opip second put-line)各ペアの2番目の要素(元のレコード)を選択して渡す機能パイプラインを介してマッピングしますput-line

この式は(trunc (* 5 0..n) 100)新しいTXR機能を利用します。範囲は算術をサポートします。。データリスト全体の範囲を表す範囲を選択し、0..nその範囲に 5 を乗算し (切り捨てられた整数除算を使用して) 100 で除算します。これは0〜5%の範囲を提供します。

低いゼロエンドポイントは影響を受けないため、n範囲を計算せずに範囲を計算してから形成することでこれを行うことができます0..(trunc (* 5 n) 100)。下限エンドポイントがゼロの場合、利点はありません。

しかし、2番目の5番目のパーセンタイルを取得するためにコードを変更するとします。これにより、範囲演算はより簡単になります(trunc (* 5 (+ 0..n n)) 100)。範囲nに追加し([0、n)から[n、2n)に置き換えて、前と同様に5%に縮小します。つまり、5を掛けて100に切ります。0..n

答え3

これはサンプルファイルで動作します。

sort -gk 2,2 file.txt | tail -n2
446 16480
386 16501,5

確かなことについては最初の5これにはいくつかの追加ロジックが必要です。これは、ファイルの改行数に小数点以下の桁数が0の0.05を掛けて小数点以下の桁数を削除します。

sort -gk 2,2 file | tail -n$(bc <<<"scale=0; ($(wc -l < file)*.05)/1" | cut -d\. -f1)
446 16480
386 16501,5

関連情報