CSVは”,”(カンマ)などの区切り文字と改行でデータが区切られた一般的なテキストフォーマットで、目にする機会も多いと思います。本記事では、csvモジュールを使ってCSVファイルの読み込み、および書き込み方法についてまとめます。
# 2019/3/11 記事更新
確認した環境
- OS: Ubuntu16.04LTS
- Python 3.7.2
“CSV”とは?
- CSVは、”Comma Separated Values(カンマ区切り値)”の略
- カンマなどの区切り文字と改行でデータが区切られたプレーンテキストファイル
- Excelなどのスプレッドシートやデータベース間のデータのやり取りで一般的な形式
- 大文字のCSVは一般的なファイル形式のことを指す場合、小文字のcsvはモジュールやパラメータを指す場合(っぽいです。)
CSVファイルの読み込み(csv.reader)
読み込みの手順
(1)csvモジュールのインポート
csvモジュールはPythonの標準組み込みライブラリなので、新たに何かをインストールをする必要はありません。
>>> import csv
(2)open()関数を ‘r’モード でCSVファイルを開き、fileオブジェクトを生成。
※ 引数パラメータとして newline=’ ‘ を設定しておく(と良いと公式に記載あり)。
※ open()関数については、こちらの記事でもまとめています。
>>> f = open('sample.csv', 'r', newline='', encoding='utf-8')
(3)reader()メソッドに上記のfileオブジェクトを渡し、Readerオブジェクトを生成
- ReaderオブジェクトはCSVファイルの行を要素としたイテレータです。
- 読み込まれた各行は、文字列のリストとなります。
- 読み込んだデータを各行毎に標準出力へ表示するには、例えば以下の例のようにfor文を使うと出来ます。
- 尚、データは一旦読み出すと(イテレータなので)readerオブジェクトの中身が無くなってしまうので注意です。再度利用するには、ファイルを再オープンします。
>>> r = csv.reader(f)
>>> for l in r:
>>> print(l)
実際にCSVファイルを読み込んでみる
例として、下記の内容が記載されたCSVファイル(sample.csv)を読み込んでみます
(ファイルはこちらにアップしています。)
年月日,平均気温(℃),降水量の合計(mm),降水量の合計(mm),平均風速(m/s)
2018/8/10,29.8,0,1,3.8
2018/8/11,28.7,0.5,0,2.3
2018/8/12,27.7,0.0,0,2.2
2018/8/13,27.5,10.5,0,2.0
2018/8/14,28.8,0,1,3.8
2018/8/15,29.7,0,1,5.8
コード例を示します。
>>> import csv
# CSVファイルを開く
>>> with open('sample.csv', 'r', newline='', encoding='utf-8') as f:
... r = csv.reader(f) # CSVファイルを読み込んでReaderオブジェクトを生成
... for l in r:
... print(l)
...
['年月日', '平均気温(℃)', '降水量の合計(mm)', '降水量の合計(mm)', '平均風速(m/s)']
['2018/8/10', '29.8', '0', '1', '3.8']
['2018/8/11', '28.7', '0.5', '0', '2.3']
['2018/8/12', '27.7', '0.0', '0', '2.2']
['2018/8/13', '27.5', '10.5', '0', '2.0']
['2018/8/14', '28.8', '0', '1', '3.8']
['2018/8/15', '29.7', '0', '1', '5.8']
不要な行をスキップする
上記の例は、CSVファイルに記載されているデータの行を全て読み込んでいました。
しかし、ファイルの最初の数行はデータについての説明だったり、ラベルデータだったりすることがよくあります。
このような場合は、line_num属性(行番号を表す)を使って不要な行をスキップできます。
>>> with open('sample.csv', 'r', newline='', encoding='utf-8') as f:
... r = csv.reader(f)
... for l in r:
... if r.line_num == 1: # ここで不要な行をスキップさせる
... continue
... print(l)
...
['2018/8/10', '29.8', '0', '1', '3.8']
['2018/8/11', '28.7', '0.5', '0', '2.3']
['2018/8/12', '27.7', '0.0', '0', '2.2']
['2018/8/13', '27.5', '10.5', '0', '2.0']
['2018/8/14', '28.8', '0', '1', '3.8']
['2018/8/15', '29.7', '0', '1', '5.8']
辞書形式での読み出し
CSVファイルを読み出す際には辞書形式で読み出すことも可能です。
この場合はDictReaderメソッドを使います。返り値はOrderedDIct形式です。
以下の例では、通常の辞書型にするために出力時にdict()関数で辞書型に変換をしています。
>>> with open('sample.csv', 'r', newline='', encoding='utf-8') as f:
... r = csv.DictReader(f)
... for l in r:
... print(dict(l)) # 辞書型に変換
...
{'年月日': '2018/8/10', '平均気温(℃)': '29.8', '降水量の合計(mm)': '1', '平均風速(m/s)': '3.8'}
{'年月日': '2018/8/11', '平均気温(℃)': '28.7', '降水量の合計(mm)': '0', '平均風速(m/s)': '2.3'}
{'年月日': '2018/8/12', '平均気温(℃)': '27.7', '降水量の合計(mm)': '0', '平均風速(m/s)': '2.2'}
{'年月日': '2018/8/13', '平均気温(℃)': '27.5', '降水量の合計(mm)': '0', '平均風速(m/s)': '2.0'}
{'年月日': '2018/8/14', '平均気温(℃)': '28.8', '降水量の合計(mm)': '1', '平均風速(m/s)': '3.8'}
{'年月日': '2018/8/15', '平均気温(℃)': '29.7', '降水量の合計(mm)': '1', '平均風速(m/s)': '5.8'}
CSVファイルの書き込み(csv.writer)
書き込みの手順
(1)通常のファイル書き込みと同様に”w”モードでfileオブジェクトを生成します。
※ 引数パラメータとしてnewline=”を設定しておく(と良いと公式に記載あり)。
>>> import csv
>>> f = open('sample_w.csv', 'w', newline='')
(2)生成したfileオブジェクトをwriter()メソッドに渡し、Writerオブジェクトを生成します。
>>> w = csv.writer(f)
(3)writerow()関数を使ってデータ(文字列か数値のイテラブル)をWriterオブジェクトに書き込みます。返り値は、ファイルに書き出した行の文字数です。
>>> w.writerow(***文字列か数値のイテラブル*****)
実際にCSVファイルに書き込んでみる
上記をまとめて、CSVファイルへの書き込みのコード例を以下に示します。
>>> with open('sample_w.csv', 'w', newline='') as f:
... w = csv.writer(f) # writerオブジェクトを生成
... w.writerow(['a', 'b', 'c', 'd']) # データを書き込む
... w.writerow([1, 2, 3, 4]) # データを書き込む
... w.writerow(['a b c', 'd, e, f', '1 2 3', '4,5,6'])# データを書き込む
...
9
9
31
出力されたファイルを以下に示します。(sample_w.csv)
要素の中の”,(カンマ)”もエスケープ処理されているのが分かるかと思います。
a,b,c,d
1,2,3,4
a b c,"d, e, f",1 2 3,"4,5,6"
辞書形式での書き込み
DictWriterメソッドを使って辞書形式のデータをCSV形式にすることもできます。
第二引数feildnamesには、writerow()関数で渡された辞書の値がどのような順番でファイルに書かれるかをリスト形式で設定します。
以下に例を示します。
>>> with open('sample_w2.csv', 'w', newline='') as f:
... w = csv.DictWriter(f, fieldnames=["date", "name", "Qty"])
... w.writeheader()
... w.writerow({'date':'Feb14', 'name':'Taro', 'Qty':10})
... w.writerow({'date':'May15', 'name':'Jiro', 'Qty':24})
... w.writerow({'date':'Jun7', 'name':'Tom', 'Qty':5})
...
15
15
12
出力結果を示します。(sample_w2.csv)
辞書形式からCSV形式に変換できていることが確認できます。
Feb14,Taro,10
May15,Jiro,24
Jun7,Tom,5
まとめ
今回は、CSVファイルの読み出し・書き込み方法についてまとめました。