私はかなり大きなデータセット〜5億行を持っています。データセットは以下の通りです。列1は浮動小数点数、列2はmac id(デバイスID)です。
1616.93,ac:22:0b:a6:22:c3
2872.32,c0:bd:d1:36:bb:49
3314.55,d4:0b:1a:39:19:b2
2854.11,18:f6:43:64:81:67
3540.68,18:f6:43:64:81:67
3856.91,ac:22:0b:a6:22:c3
2497.93,d4:0b:1a:39:19:b2
この問題は、列2をグループ化してから約100,000個のランダムサンプルを出力し、その特定のグループの列1で最大値を見つけることが必要です。
中間出力は次のとおりです(col1でグループ化)。
1616.93,ac:22:0b:a6:22:c3
3856.91,ac:22:0b:a6:22:c3
2854.11,18:f6:43:64:81:67
3540.68,18:f6:43:64:81:67
2872.32,c0:bd:d1:36:bb:49
3314.55,d4:0b:1a:39:19:b2
2497.93,d4:0b:1a:39:19:b2
その後、グループ化された各列の最大値が必要です。出力は次のとおりです。
3856.91,ac:22:0b:a6:22:c3
3540.68,18:f6:43:64:81:67
2872.32,c0:bd:d1:36:bb:49
3314.55,d4:0b:1a:39:19:b2
最後のステップは本当にランダムなサンプルを得ることです。出力は次のとおりです。
3540.68,18:f6:43:64:81:67
2872.32,c0:bd:d1:36:bb:49
これを行う方法についてのアイデアがあります。私はちょうどLinuxを使い始めましたが、これは難しいことをする方法がわかりません。どんな助けでも大変感謝します。
答え1
努力する
BEGIN { srand() ;r=0 ; FS="," ; before="" ; }
{ if ( $1 > V[$2]) V[$2]=$1 ;
if ( before != $2 && before != "" ) {
r=rand()*100 ;
if ( r > 50 ) printf "%s,%s\n",V[before],before ;
}
before=$2 ;
} data-file.txt
どこ
if ( $1 > V[$2]) V[$2]=$1
; macの最大値を取得します。if ( before != $2 && before != "" ) {
新しいmac値が表示されたときr=rand()*100 ; if ( r > 50 ) printf "%s,%s\n",V[before],before ;
任意の値を計算して50%を超えると印刷します。 (5%、95%に変更可能)
答え2
5億行は大量のデータなので、これを処理するためのよりスケーラブルな方法を探したいかもしれません。つまり、標準のLinuxユーティリティを使用してこれを行うことができます。
データが名前付きファイルにあると仮定すると、data.txt
以下を使用して端末に印刷できますcat
。
$ cat data.txt
1616.93,ac:22:0b:a6:22:c3
2872.32,c0:bd:d1:36:bb:49
3314.55,d4:0b:1a:39:19:b2
2854.11,18:f6:43:64:81:67
3540.68,18:f6:43:64:81:67
3856.91,ac:22:0b:a6:22:c3
2497.93,d4:0b:1a:39:19:b2
sort
その後、optionsを使用してこの出力をパイプに接続できます-t ',' -k 2
。これらのオプションは、sort
カンマを区切り文字として使用してデータを分割し、2番目の列の値に基づいてソートするように指示します。
$ cat data.txt | sort -t ',' -k 2
2854.11,18:f6:43:64:81:67
3540.68,18:f6:43:64:81:67
1616.93,ac:22:0b:a6:22:c3
3856.91,ac:22:0b:a6:22:c3
2872.32,c0:bd:d1:36:bb:49
2497.93,d4:0b:1a:39:19:b2
3314.55,d4:0b:1a:39:19:b2
sort
次のミッションではオプションを使用する必要があります-t ',' -k 1 -r
。これにより、カンマを区切り文字として使用し、最初の列の値を使用してソートされます。-r
最大の項目を最初に提供し、適切な順序で並べ替えます。
$ cat data.txt | sort -t ',' -k 1 -r
3856.91,ac:22:0b:a6:22:c3
3540.68,18:f6:43:64:81:67
3314.55,d4:0b:1a:39:19:b2
2872.32,c0:bd:d1:36:bb:49
2854.11,18:f6:43:64:81:67
2497.93,d4:0b:1a:39:19:b2
1616.93,ac:22:0b:a6:22:c3
sort
次に、このオプションを使用して、上記の例の出力をパイプに再接続する必要があります-t ',' -k 2 -u
。以前と同様に、sortは2番目の列を使用するように指示しますが、新しいオプションはsortに固有の項目のみを保持するように指示し-t ','
ます。-k 2
-u
最初の列の値に基づいてデータをソートしたため、一意の項目を見つけると、最も高い項目が最初に検索されます。これにより、各 MAC アドレスに対して最高の単一値が提供されます。
$ cat data.txt | sort -t ',' -k 1 -r | sort -t ',' -k 2 -u
3540.68,18:f6:43:64:81:67
3856.91,ac:22:0b:a6:22:c3
2872.32,c0:bd:d1:36:bb:49
3314.55,d4:0b:1a:39:19:b2
最後に、ランダムサンプルを取得するには、shuf
次のオプションを使用できます-n 2
。ここで、2 は所望のランダムなサンプル数です。
$ shuf data.txt -n 2
3856.91,ac:22:0b:a6:22:c3
3314.55,d4:0b:1a:39:19:b2
答え3
記録用。これはうまくいくようです。他のオプションは機能しません。
sort -t "," -k2,2 -k1,1 -r output.txt| awk -F "," '!a[$2]++'|head -100