データの検索・対応付けを行う強力かつ簡単な手法の一つにExcelにおけるvlookupがあります。
vlookupは検索キーとなる1列と、検索対象となるデータ行列を対象に行う処理です。検索キーに合致する、データ行列の1列目のある行を見つけ出し、必要なデータを抽出します。
先日、膨大な時系列データに対してvlookupを行ったところ、1台のPCでは半日以上(保存するたび)、もう1台のPCではExcelが落ちるという有様になってしまいました。
他にも手立てはあるかもしれませんが、面倒になったのでawkで同様の処理を実装しました。
実行時の引数として、list1.txtにはキー列となるデータの入ったファイルを、list2.txtには対象となるデータ行列のファイル(いずれもCSVを想定)を指定します。
Excelでは指定した1列だけを抽出しますが、このプログラムでは2列目以降をすべて抽出します。
# awk版vlookup # N.Amano # v 3.0 : 2018/10/25 # v 1.0 : 2018/10/25 # # awk -f vlookup03.awk -v leftfile=list1.txt list2.txt # BEGIN { FS=","; # 検索対象データの一括読み込み # 1行目をヘッダーとする getline; printf("%s\n", $0); # 残りをメモリー上に読み込み while (getline > 0) { data2[$1] = $0; } # 検索キーを1行ずつ読み込んで検索 while ((getline < leftfile) > 0) { outLine = data2[$1]; if (outLine == null) { outLine = $1; } printf("%s\n", outLine); } }
最初に作ったバージョンでは使用メモリー量を抑制するために、両方のファイルを逐次読み込みとしました。数時間で終わるだろうと夜間放置しておきましたが、半日で半分しか処理が終わっていませんでした…。
そこで、しょせんはテキストファイル、使用メモリー量もたかがしれているというように考え直し、検索するために何度も繰り返しアクセスするデータ行列をオンメモリーとすることにしました。速度差は計測するまでもないほど違いました(このプログラムなら数秒で終わった)。
コーディングの時間とこのブログを書く時間を合わせても、圧倒的な時間削減につながりました。