カネキン伊藤テック

CSVファイルの扱い

Pythonには組み込みライブラリ csv があり、とくに外部ライブラリをインストールしなくても import csv することでCSV形式のファイルの読み書きを簡単に行うことができる。 Excelが出力するCSV形式が最もこの世に出回っているCSVデータ形式であり、Pythonの csv ライブラリもデフォルトでExcel方言形式で読み込み・書き出しを行うようになっている。(そしてExcel方言形式はRFC4180として2005標準化されたようである。)

CSVファイルを1行ずつ処理する

csv.reader を使えばセルごとのデータを行単位で簡単にパースされた結果として得ることができる。
これが基本形式で、イテレーターで処理しているのでCSVファイルがとてつもなく大きくても1行ずつ処理できる。
CSVファイルがそこまで大きくない場合は後述のセクションの方法で一気に読みこんでしまうのが簡便だ。

import csv

csv_f = "./data.csv"

# shift_jisなど他のエンコーディングのCSVファイルを読む場合は open() に encoding="shift_jis" などと指定する
with open(csv_f) as fh:
	reader = csv.reader(fh)

	for i, row in enumerate(reader):
		if i == 0:  # enumerateを使うとインデックスと一緒にループできるので何番目の論理行かわかりやすい
			# ヘッダーの場合の処理
			header = row
			continue
		
		print(row)  # row は各要素が文字列の list

CSVファイルを全てメモリにlistとして読み込む

csv.readerfor でイテレーションできるということは, list() に渡せば list になるということなので以下のようにすると全部メモリにガバっと読み込むことができる。

import csv

csv_f = "./data.csv"

# shift_jisなど他のエンコーディングのCSVファイルを読む場合は open() に encoding="shift_jis" などと指定する
with open(csv_f) as fh:
	reader = csv.reader(fh)
	lines = list(reader)  # 一気に読み込む

	# ヘッダがあるCSVの場合、以下のようにすると扱いやすい
	header = lines[0]  # headerは各要素がstrのlist
	data_rows = lines[1:]  # data_rowsは「各要素がstrのlist」のlist

CSVファイルを作成する

csv.writer クラスを使えば簡単に listtuple に1行分のデータを詰めて writerow() で書き出していくことができる。

header = ["col1", "col2", "col3"]
data_rows = [
	["row1_val1", "row1_val2", "row1_val3"],
	["row2_val1", "row2_val2", "row2_val3"]
]

out_f = "./out.csv"

# Shift JIS のCSVを作りたい場合はopen()に encoding="shift_jis" などと指定するとよい
with open(out_f, "w") as fh:
	writer = csv.writer(fh)

	# まずヘッダを書き込む
	writer.writerow(header)

	# ヘッダ以外のデータ部分を書き込む
	for data_row in data_rows:
		writer.writerow(data_row)

かならずしもこの例のようにあらかじめ全てのデータをlistなどに保持しておく必要はなく、データベースからの出力をイテレーションで書き出すなどの書き出し方をすればマシンのメモリ容量を超えるような大きさのCSVデータもちゃんと書き出せる。

テンポラリファイルを使わずにメモリ上にCSV形式のデータを作りたい場合は csv.writer() は file like なオブジェクトを引数に取るので io.StringIO を使うとよいだろう。

Excel方言

CSVのExcel方言形式は以下のようなシンプルなルールでエンコードされている。

  • 一行はコンマで区切られたセルデータの繰り返しのあと、改行(CRLF)で次の行と区切られる
  • セルデータ中に改行またはダブルクオートが入っている場合はセルの値をダブルクオートで囲む
  • セルデータ中にあるダブルクオートはダブルクオート2つに置換される。(上述のダブルクオートで囲むルールも併せて適用される)
  • その他は普通のCSVと一緒。セルとセルの間にはコンマが、行の終わりには改行がくる。

書き出す際は しかし改行をセル中に許すため \n で論理行(データの1行ぶん)を必ずしも意味しないことから意外とパースするのがめんどくさいため、 csv のような ライブラリで読み込むのが便利である。

CRLFというのはCR(Pythonの文字列リテラルで表現すると "\r")とLF(Pythonの文字列リテラルで表現すると "\n")の2バイトのことである。

参考リンク