2017/10/06更新

[Python] csvやtsvの読み書きを行う(csvモジュールの利用)

このエントリーをはてなブックマークに追加            

こんにちは、@yoheiMuneです。
今日はPythonでのCSVやTSVの扱い方をブログに書きたいと思います。
画像


目次




csvモジュールを利用する

PythonではCSVファイルやTSVファイルを扱うために、csvという標準モジュールが用意されています。名前からはcsv専用に見えますが、後述のdelimiterを指定することで、様々なフォーマットに対応できます。
簡単なCSVであれば、自前でファイルを開いて、カンマでスプリットすることで処理できますが、ダブルクォートで文字列を囲ったり、エスケープ処理したりが必要な場合には、このモジュールを使うと便利です。

以下のようにインポートして使います。
import csv
それでは具体的な使い方を見てみたいと思います。



CSVへ書き出し

CSVを作成するにはcsv.writerを用います。具体的には以下のような実装を行います。
# CSVの書き込み

# 「newline=""」を指定してファイルを開く(改行はcsvモジュールに任せる)
with open("a.csv", "w", newline="") as f:

    # 「delimiter」に区切り文字、「quotechar」に囲い文字を指定します
    # quotingにはクォーティング方針を指定します(後述)
    writer = csv.writer(f, delimiter=",", quotechar='"', quoting=csv.QUOTE_MINIMAL)

    # writerowに行列を指定することで1行分を出力できます
    writer.writerow(["name", "age"])
    writer.writerow(["Yohei", 31])
    writer.writerow(["Junji", 32])

    # カンマが含まれる場合にも、自動的に対応してくれます
    writer.writerow(["Kami,Shin", 50])

    # 囲い文字が含まれる場合にも、自動的にエスケープしてくれます
    writer.writerow(['Cha"Shu', 50])  

    # 改行が含まれていても対応できます
    writer.writerow(["AA\nBB", 21])  # 改行も対応
そして上記の出力結果が、以下になります。
name,age
Yohei,31
Junji,32
"Kami,Shin",50
"Cha""Shu",50
"AA
BB",21
ここではquoting=csv.QUOTE_MINIMALを指定しているため、必要な箇所だけに囲い文字(")が付与されています。



CSVファイルの読み込み

上記で作成したCSVを読み込んでみたいと思います。読み込みにはcsv.readerを利用します。
# CSVの読み込み

# 書き込みと同じく、newline="" を指定します.
with open("a.csv", newline="") as f:

    # 書き込みと同じ設定(delimiterとquotechar)を指定します.
    reader = csv.reader(f, delimiter=",", quotechar='"')

    # 1行ずつ読み込みます.
    for row in reader:
        print(row[0], row[1])
上記の読み込み結果は以下の通りです。
name age
Yohei 31
Junji 32
Kami,Shin 50
Cha"Shu 50
AA
BB 21
クォート処理とかされていたり、改行があったりしますが、その辺をうまく取り込んでくれています。
なお、csv.readerではヘッダーを判定していい感じに処理することができないので、ヘッダー処理が必要なら、「1行目なら・・・」という処理を実装する必要があります。



DictWriterの利用

上記の書き込み例だと、配列を渡していましたが、辞書型を渡して書き込むこともできます。具体的には以下のように実装します。
# DictWriterの利用例

with open("b.csv", "w", newline="") as f:

    # 要素順を指定します(dictでは順序がわからないため)
    fieldnames = ["firstname", "lastname"]

    # writerオブジェクトを作成します.
    writer = csv.DictWriter(f, fieldnames=fieldnames, delimiter=",", quotechar='"')

    # writeheaderでヘッダーを出力できます.
    writer.writeheader()

    # writerowで1行分を出力します.
    writer.writerow({ "firstname" : "AA", "lastname" : "BB" })
    writer.writerow({ "firstname" : "CC", "lastname" : "DD" })
出力結果は以下の通りです。
firstname,lastname
AA,BB
CC,DD
辞書型でデータを持っていることも多いので、この機能も便利ですね。



DictReaderの利用

読み込みでも同じく、辞書型を利用することができます。具体的には以下のように実装します。
# DictReader

with open("b.csv", newline="") as f:

    # 読み込みではヘッダ指定は不要です.
    # 1行目をヘッダ要素として利用します.
    reader = csv.DictReader(f, delimiter=",", quotechar='"')

    # 1行ずつ取得することができます.
    for row in reader:
        print(row["firstname"], row["lastname"])
ヘッダーなしのCSVファイルの場合には、csv.DictReaderの引数にfieldnamesを指定して、フィールド一覧を指定します。上記の読み込み結果は以下のように出力されます。
AA BB
CC DD



quotingの指定

クォーティング(囲い文字)について、どのような方針で出力するのかを指定することができます。具体的には以下の値を指定することができます。
設定値 内容
csv.QUOTE_ALL 全てのフィールドをクォートします。
csv.QUOTE_MINIMAL フィールドに、区切り文字、囲い文字、改行、が含まれる場合にのみクォートします。
csv.QUOTE_NONNUMERIC 全ての非数値フィールドに対して、クォートします。
QUOTE_NONE 全くクォートしません。

参考:https://docs.python.jp/3/library/csv.html#csv.QUOTE_ALL



基本的にはcsv.QUOTE_ALLcsv.QUOTE_MINIMALを使えばいいかなと思います。



参考資料

今回の実装を行うのに、以下の資料を参照しました。ありがとうございます。

14.1. csv — CSV ファイルの読み書き — Python 3.6.1 ドキュメント



最後に

このモジュールがあれば、csv/tsvの読み書きができるので、仕事でも非常に助かってます。今後も色々と使っていけたらと思います。

最後になりますが本ブログでは、Python・Go言語・Linux・フロントエンド・Node.js・インフラ・開発環境・Swift・Java・機械学習など雑多に情報発信をしていきます。自分の第2の脳にすべく、情報をブログに貯めています。気になった方は、本ブログのRSSTwitterをフォローして頂けると幸いです ^ ^。

最後までご覧頂きましてありがとうございました!





こんな記事もいかがですか?

RSS画像

もしご興味をお持ち頂けましたら、ぜひRSSへの登録をお願い致します。