複数の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 を読んでいると、CSV はWikipedia:フラットファイルデータベースに該当する。データベースの一種として考えるならば、スクリプトでマージするよりも SQL でマージする方が適している。実際スクリプトで書いてみると無理やりな感がある。以前はもっと無理やりな方法として、UNIX コマンドの grep, cut, sed 辺りを駆使したシェルスクリプトでマージしていた気がする。情報を蓄積・検索するためにデータベースを利用するのではなく、日常のちょっとしたツールの一つとしてデータベースが利用できると便利そうだ。
あとは、CSV を表計算ソフト、データベースで扱いやすくするため、CSV を作成する際には、以下の点を実行しておくとよい。
参考情報
【収集用メールアドレス】:q1w2e3w2@gmail.com