pythonでcsvファイルの編集をする
pythonでcsvファイルの編集をする
今回、職場で後輩から「csvファイルをArcGISに読ませる前処理で編集、加工しないといけないんですけど、pythonでできますか?」という質問があった。
csvファイルの列を結合したり、入れ替えたり、文字を置換したり、特定の行だけ削除したり・・・
簡単にできるのでここでも紹介する。
※下の図は、csvファイルをExcelで開いた例
※注:編集後の電話番号はExcelで開くと、数値型に変換されて先頭の0がなくなるが、見やすくするために加工した。
スクリプトの全文
※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(",") # 変換後のカンマ区切りの雛形を作り、変換処理した値を入れ込む row = "{},{},{},{}\n".format( line[0], line[1] + " " + line[2], line[3], line[4].replace("-","") ) # 書き出し用のファイルに出力 out_file.write(row) # 2つのファイルを閉じる file.close() out_file.close()
テキストで開いても正しく編集されたことがわかる。
細部補足説明
ファイルを開く open(filename,mode)
テキストファイルを開くには組み込み関数のopenメソッドを使う。
# 編集したいファイルを開く file = open("顧客データ.csv","r") # 書き出し用のファイルを開く out_file = open("出力データ.csv","w")
openのmodeはだいたい次の3つを多用する。
r | 読み取り用 ファイルが存在しない場合はエラー(デフォルト) |
w | 書き込み用 ファイルが存在する場合は上書きする |
a | 書き込み用 ファイルが存在する場合は末尾に追記する |
ファイルに書き込み write(string)
ファイルの出力には、出力したいファイルオブジェクトに対してwriteメソッドを使う。
編集後の列に合わせて書き出し用のファイルにヘッダーを記述する。
※最後の改行コード(\n)を忘れずに入れる。
# 書き出し用ファイルのヘッダーを記述 out_file.write("ID,姓名,住所,電話番号\n")
ファイルを1行飛ばして全行読み取る
元ファイルは、ヘッダー(先頭行)を除いたレコード部分が取得できればよい。
readlineメソッドを使うと、1行飛ばすことができるので、その後に、readlinesメソッドで全行を読み取る。
※ヘッダー部分が2行や3行あるcsvファイルも、readlineメソッドを飛ばしたい行数分記述すればよい。
# 元ファイルのヘッダーをreadlineメソッドで1行飛ばす file.readline() # 元ファイルのレコード部分をreadlinesメソッドで全行を読み取る lines = file.readlines()
for文で1行ずつ読み取り、編集後の値を作成する
readlinesメソッドで読み取ると、行の最後に改行コード(\n)が含まれる。
編集作業では予期しない結果を招く恐れがあるので、これを一度replaceメソッドで取り除く。
次に、splitメソッドでカンマ区切りのリストの値で返す。
リストにすることにより、各列をインデックスで切り出せる。
- line[0] : ID
- line[1] : 姓
- line[2] : 名
- line[3] : 住所
- line[4] : 電話番号
最後にカンマ区切りの雛形を作ったら、編集後の値を入れ込み、ファイルに書き出してあげればOK
※ここでも、各行ごと最後に改行コード(\n)を入れ忘れない。
※今回の場合であれば、結果的に改行コードを最初から取らなければよいが、最終フィールドを編集する場合は、予期しない結果になる可能性があるため、予め改行コードを取って置き、書き出す時にまた付ける方が安全
# for文で1行ずつ取得 for line in lines: # 改行コードをブランクに置換 line = line.replace("\n","") # カンマ区切りでリストの値に変換する line = line.split(",") # 変換後のカンマ区切りの雛形を作り、変換処理した値を入れ込む row = "{},{},{},{}\n".format( line[0], line[1] + " " + line[2], line[3], line[4].replace("-","") ) # 書き出し用のファイルに出力 out_file.write(row)
組み込み関数しか使っていないが、個人的には結構おもしろいロジックだなと思った。
質問や記事の誤りがありましたらコメントお願いします。
次の記事
pythonで複数行のcsvファイルを1行にする(正規化) - memopy
【別の記事】tkinterで家計簿アプリを作りました。
memopy.hatenadiary.jp