複数のCSVファイルの統合(マージ)

2 つの CSV ファイルがあり、それらを統合(マージ)する必要がありました。どうすれば手軽にできるか試してたので、メモとしてまとめます。

対象となる CSV ファイルは以下の 2 つ。CSV A, CSV B に含まれる parmA, paramB, paramC, paramD, paramE をまとめて、CSV として出力する。CSV A, CSV B にそれぞれ同じパラメータ値があります。これをキーとして統合するのが手っ取り早そう。最初 CSV A には paramB がなかった。さすがにそれだとめんどくさいと思い、CSV A に paramB を追加しておきました。

ファイル パラメータ数 パラメータ
CSV A 2 paramA, paramB
CSV B 4 paramB, paramC, paramD, paramE

OpenOffice Base にインポートし、クエリでマージする

CSV A, CSV B をそれぞれ OpenOffice Base にインポートして、テーブル登録。登録したテーブルから SQL の SELECT 文で出力。Microsoft Office が手元にないため、Access が利用できず、OpenOffice Base を初めて利用しました。そもそも Base には CSV のインポート/エクスポート機能がない模様。インポートに関しては、データベースとして登録することで CSV ファイルを取り込むことができる。だが、エクスポートはちょっと面倒。インポートしたテーブルなり、登録したクエリなりを一度コピーして、OpenOffice Clac に葉貼り付け、そして Calc にて CSV 形式で保存するというステップが必要。MS Access ならもっと手軽なんだろうな。

参考情報

スクリプトでマージする

スクリプトで、CSV ファイルをマージする。ここでは Python で簡単なスクリプトを書いてみた。例外処理等は割愛。

まず、CSV A を読み込み、辞書型 dicA に paramB をキーとして、paramA を代入する。続いて、CSV B を 1 行毎に読み込み、共通のパラメータである、paramB を dicA で検索する。dicA で paramB に一致する値があったら、辞書 dicA から paramA の値を得て、paramA, paramB, paramC, paramD, paramE の値をリストとして、リスト arrayC に格納している。最後に arrayC のリストを CSV 形式で出力する。

import sys

fina = open(sys.argv[1], "r")
finb = open(sys.argv[2], "r")

dicA = {}
arrayC = []

for a in fina.readlines():
	# readlines() では末尾に改行コードが含まれるため、改行コードは除去する
	a = a.rstrip('\n')
	[p1, p2] = a.split(',')
	if p2 not in dicA:
		dicA[p2] = p1

for b in finb.readlines():
	b = b.rstrip('\n')
	[p1, p2, p3, p4] = b.split(',')
	if p1 in dicA:
		arrayC.append([dicA[p1], p1, p2, p3, p4])

for c in arrayC:
	print ",".join(c)

fina.close()
finb.close()

一行一行検索で発見して、コピーする

やってません。これやったら、エンジニアではないなと思いますね。それぞれの CSV ファイルが 2,3 行で手でまとめる方が早いけど、大量のデータを扱う時に手動はないな。

やってみて気がついたこと

Wikipedia を読んでいると、CSVWikipedia:フラットファイルデータベースに該当する。データベースの一種として考えるならば、スクリプトでマージするよりも SQL でマージする方が適している。実際スクリプトで書いてみると無理やりな感がある。以前はもっと無理やりな方法として、UNIX コマンドの grep, cut, sed 辺りを駆使したシェルスクリプトでマージしていた気がする。情報を蓄積・検索するためにデータベースを利用するのではなく、日常のちょっとしたツールの一つとしてデータベースが利用できると便利そうだ。

あとは、CSV表計算ソフト、データベースで扱いやすくするため、CSV を作成する際には、以下の点を実行しておくとよい。

  • 関連ある CSV ファイルには照合キーとなる同じフィールド値を持たせる
  • CSV ファイルの一行目はフィールド名とする。
  • 区切り文字である「,」を含む場合、フィールド値を「"」または「'」で括る

参考情報

【収集用メールアドレス】:q1w2e3w2@gmail.com