pythonで複数行のcsvファイルを1行にする(正規化)
pythonで複数行のcsvファイルを1行にする(正規化)
今回も前回に引き続き、pythonでcsvファイルの編集を行う。
前回の記事はこちら
pythonでcsvファイルの編集をする - memopy
今回は、複数行のレコードを1行にするいわゆる正規化の方法について紹介する。
下図のようなcsvファイルを想定する。
このように必要な情報が1行にまとまっていない、情報の繰り返しがあるデータはデータベースでは非常に扱いづらい。
これを1行にし、繰り返しをなくすことを正規化という。
スクリプト全文
※python3で作成したが、python2でも動くはず。
# -*- coding:utf-8 -*- # 編集したいファイル(元ファイル)を開く file = open("顧客データ.csv","r") # 書き出し用のファイルを開く out_file = open("出力データ.csv","w") # 書き出し用ファイルのヘッダーを記述 out_file.write("ID,氏名,都道府県,電話番号\n") # 元ファイルのヘッダーをreadlineメソッドで1行飛ばす file.readline() # 元ファイルのレコード部分をreadlinesメソッドで全行を読み取る lines = file.readlines() # for文で1行ずつ取得 for line in lines: # 改行コードをブランクに置換 line = line.replace("\n","") # カンマ区切りでリストに変換する line = line.split(",") # もし取得した行の先頭が#だったら、都道府県名を取得する。 if line[0][0] == "#": pref = line[0].replace("#","") # 取得した行が都道府県でなかったら、書き出しの処理 else: # 変換後のカンマ区切りの雛形を作り、変換処理した値を入れ込む row = "{},{},{},{}\n".format( line[0], line[1], pref, line[2] ) # 書き出し用のファイルに出力 out_file.write(row) # 2つのファイルを閉じる file.close() out_file.close()
正しく変換された。
細部補足説明
前回の記事から変更したロジックは次の部分のみ。
# もし取得した行の先頭が#だったら、都道府県名を取得する。 if line[0][0] == "#": pref = line[0].replace("#","") # 取得した行が都道府県でなかったら、書き出しの処理 else: # 変換後のカンマ区切りの雛形を作り、変換処理した値を入れ込む row = "{},{},{},{}\n".format( line[0], line[1], pref, line[2] ) # 書き出し用のファイルに出力 out_file.write(row)
このcsvファイルは、都道府県情報が入っている行の1文字目は#となっている。
そのため、1文字目が#のときは、変数に都道府県を格納だけし、
1文字目が#でない行(=繰り返し部分)で、格納した変数(都道府県)も含めて、csvへ書き出しの処理をする。
都道府県の変数は、繰り返し部分を処理している間は、同じ値を持ち続けるという仕組みだ。
このように繰り返し部分とそうでない部分に規則性があれば、if-elif-else構文で正規化できる。
このように正規化されていないデータは結構世の中にあるので、意外と使う機会も多いであろう。
質問や記事の誤りがありましたらコメントお願いします。
【別の記事】tkinterで家計簿アプリを作りました。
memopy.hatenadiary.jp