memopy

pythonで作ってみました的なブログ

pythonでcsvファイルの編集をする

pythoncsvファイルの編集をする

今回、職場で後輩から「csvファイルをArcGISに読ませる前処理で編集、加工しないといけないんですけど、pythonでできますか?」という質問があった。
csvファイルの列を結合したり、入れ替えたり、文字を置換したり、特定の行だけ削除したり・・・
簡単にできるのでここでも紹介する。

※下の図は、csvファイルをExcelで開いた例
f:id:memopy:20170605192055p:plain
※注:編集後の電話番号は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()

テキストで開いても正しく編集されたことがわかる。
f:id:memopy:20170605201209p:plain

細部補足説明

ファイルを開く 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