awk版vlookup

データの検索・対応付けを行う強力かつ簡単な手法の一つに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);
	}
}

最初に作ったバージョンでは使用メモリー量を抑制するために、両方のファイルを逐次読み込みとしました。数時間で終わるだろうと夜間放置しておきましたが、半日で半分しか処理が終わっていませんでした…。

そこで、しょせんはテキストファイル、使用メモリー量もたかがしれているというように考え直し、検索するために何度も繰り返しアクセスするデータ行列をオンメモリーとすることにしました。速度差は計測するまでもないほど違いました(このプログラムなら数秒で終わった)。

コーディングの時間とこのブログを書く時間を合わせても、圧倒的な時間削減につながりました。

タグ: ,

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

*