Pythonで業務の自動化を行うためにはCSVファイルの操作が不可欠です。
この記事では、標準モジュールの csv
でCSVファイルの読み込み・書き込みを行う方法を解説します。
使用モジュール
インストール:不要
Python標準モジュールの csv
を利用します。インストールは不要です。
モジュールのインポート
csv
モジュールをインポートします。
1 | import csv |
サンプルコードの中で二次元配列を表示するために、pprintモジュールも使用しています。
1 | from pprint import pprint |
サンプルデータ
CSVファイルは以下のようなデータ seiseki.csv を使用します。
CSVファイルの読み込み(リスト型)
CSVファイルの読み込み・入力
CSVファイルの読み込みには csv.reader()
クラスを使用します。
第一引数には open()
関数で開いたファイルオブジェクトを指定します。
python実行ディレクトリにある kawa.csv を読み込みます。
1 2 3 4 5 6 7 8 9 10 11 | with open('./seiseki.csv', newline='') as f: reader = csv.reader(f) for row in reader: print(row) # ['No', '河川名', '延長(km)'] # ['1', '信濃川', '367'] # ['2', '利根川', '322'] # ['3', '石狩川', '268'] # ['4', '天塩川', '256'] # ['5', '北上川', '249'] |
reader
オブジェクトはイテレータとなるため、for 文で行ごとに出力できます。
読み込まれた各行は、文字列のリストとして返されます。
csv.reader()
で使用される主な引数は以下になります。
open()
関数でファイルを開くときは、引数に newline=''
を付けておくと安全です。
デフォルト設定は newline = None
ですが、\r\n
, \r
などの改行コードが \n
に自動変換されてしまい、意図しない場所で改行されてしまいます。
実行時に 'cp932' codec can't decode byte 0x8d in position 9
といったエラーが発生する場合は、ファイルのエンコード が utf-8 などで保存されている事が原因です。open()
関数の引数に encoding='utf-8'
等、ファイルと同じエンコードを指定すると解消されます。
二次元配列で読み込み
1行ずつではなく、二次元配列として読み込む方法です。
リスト内包表記を使用することで、二次元配列で読み込むことができます。
リスト内リストの場合は以下のようになります。
1 2 3 4 5 6 7 8 9 10 11 | with open('kawa.csv', newline='') as f: reader = csv.reader(f) row_list = [row for row in reader] pprint(row_list) # [['No', '河川名', '延長(km)'], # ['1', '信濃川', '367'], # ['2', '利根川', '322'], # ['3', '石狩川', '268'], # ['4', '天塩川', '256'], # ['5', '北上川', '249']] |
数値データを浮動小数点として読み込む
csv.reader()
で数字を読み込んでも、文字列として読み込まれます。
数値に変換したい場合は、int()
や float()
で対象のデータを変換する必要があります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | with open('kawa.csv', newline='') as f: reader = csv.reader(f) row_list = [row for row in reader] for i in range(len(row_list)): if i > 0 : row_list[i][2] = float(row_list[i][2]) pprint(row_list) # [['No', '河川名', '延長(km)'], # ['1', '信濃川', 367.0], # ['2', '利根川', 322.0], # ['3', '石狩川', 268.0], # ['4', '天塩川', 256.0], # ['5', '北上川', 249.0]] |
他の方法として、csv.reader()
の引数に quoting=csv.QUOTE_NONNUMERIC
を指定することで
引用符のない数値は浮動少数点数として読み込むことができます。
ただし、float
に変換できない要素が引用符に囲まれていないとエラーとなるので注意が必要です。
サンプルとして文字列を 「””」 で囲んであるファイル kawa_quote.csv を読み込みます。
1 2 3 4 5 6 7 8 9 10 11 | with open('kawa_quote.csv', newline='') as f: reader = csv.reader(f, quoting=csv.QUOTE_NONNUMERIC) row_list = [row for row in reader] pprint(row_list) # [['No', '河川名', '延長(km)'] # ['1', '信濃川', 367.0] # ['2', '利根川', 322.0] # ['3', '石狩川', 268.0] # ['4', '天塩川', 256.0] # ['5', '北上川', 249.0]] |
区切り文字を指定する
csv.reader()
は通常、区切り文字は「,」(カンマ)として扱います。
他の区切り文字のファイルを読み込みたい場合は、引数に delimiter
を指定します。
サンプルとして区切り文字がスペースのCSVファイル kawa_space.csv を読み込みます。
1 2 3 4 5 6 7 8 9 10 11 | with open('kawa_space.csv', newline='') as f: reader = csv.reader(f, delimiter=' ') row_list = [row for row in reader] pprint(row_list) # [['No', '河川名', '延長(km)'], # ['1', '信濃川', '367'], # ['2', '利根川', '322'], # ['3', '石狩川', '268'], # ['4', '天塩川', '256'], # ['5', '北上川', '249']] |
CSVファイルの読み込み(辞書型)
CSVファイルの読み込み・入力
csv.DictReader()
クラスを使用すると、ファイルの内容を、ヘッダをキーとした辞書型で取得する事ができます。
1 2 3 4 5 6 7 8 9 10 | with open('kawa.csv', newline='') as f: d_reader = csv.DictReader(f) for row in d_reader: print(row) # {'No': '1', '河川名': '信濃川', '延長(km)': '367'} # {'No': '2', '河川名': '利根川', '延長(km)': '322'} # {'No': '3', '河川名': '石狩川', '延長(km)': '268'} # {'No': '4', '河川名': '天塩川', '延長(km)': '256'} # {'No': '5', '河川名': '北上川', '延長(km)': '249'} |
csv.reader
と同様に reader
オブジェクトはイテレータとなるため、for 文で行ごとに出力できます。
辞書型で読み込むと readerオブジェクト.fieldnames
でカラム名の一覧が取得可能です。
また、カラム名を指定して出力することもできます。
1 2 3 4 5 6 7 8 9 10 11 12 | with open('kawa.csv', newline='') as f: d_reader = csv.DictReader(f) print('カラム名', d_reader.fieldnames) for row in d_reader: print(row['No'], row['河川名']) # カラム名 ['No', '河川名', '延長(km)'] # 1 信濃川 # 2 利根川 # 3 石狩川 # 4 天塩川 # 5 北上川 |
二次元配列で読み込み
1行ずつではなく、二次元配列として読み込む方法です。
リスト内包表記を使用することで、二次元配列で読み込むことができます。
1 2 3 4 5 6 7 8 9 10 | with open('kawa.csv', newline='') as f: d_reader = csv.DictReader(f) row_dlist = [row for row in d_reader] pprint(row_dlist, sort_dicts=False) # [{'No': '1', '河川名': '信濃川', '延長(km)': '367'}, # {'No': '2', '河川名': '利根川', '延長(km)': '322'}, # {'No': '3', '河川名': '石狩川', '延長(km)': '268'}, # {'No': '4', '河川名': '天塩川', '延長(km)': '256'}, # {'No': '5', '河川名': '北上川', '延長(km)': '249'}] |
数値データを浮動小数点として読み込む
1 2 3 4 5 6 7 8 9 10 11 12 13 | with open('kawa.csv', newline='') as f: reader = csv.DictReader(f) row_dlist = [row for row in reader] for i in range(len(row_dlist)): row_dlist[i]['延長 (km)'] = float(row_dlist[i]['延長(km)']) pprint(row_dlist, sort_dicts=False) # [{'No': '1', '河川名': '信濃川', '延長(km)': 367.0}, # {'No': '2', '河川名': '利根川', '延長(km)': 322.0}, # {'No': '3', '河川名': '石狩川', '延長(km)': 268.0}, # {'No': '4', '河川名': '天塩川', '延長(km)': 256.0}, # {'No': '5', '河川名': '北上川', '延長(km)': 249.0}] |
csv.reader()
と同様に、引数に quoting=csv.QUOTE_NONNUMERIC
を指定することで、引用符のない数値は浮動少数点数として読み込むことができます。
サンプルとして文字列を 「””」 で囲んであるファイル kawa_quote.csv を読み込みます。
1 2 3 4 5 6 7 8 9 10 | with open('kawa_quote.csv', newline='') as f: d_reader = csv.DictReader(f, quoting=csv.QUOTE_NONNUMERIC) row_dlist = [row for row in d_reader] pprint(row_dlist, sort_dicts=False) # [{'No': '1', '河川名': '信濃川', '延長(km)': 367.0} # {'No': '2', '河川名': '利根川', '延長(km)': 322.0} # {'No': '3', '河川名': '石狩川', '延長(km)': 268.0} # {'No': '4', '河川名': '天塩川', '延長(km)': 256.0} # {'No': '5', '河川名': '北上川', '延長(km)': 249.0}] |
区切り文字を指定する
csv.Dictreader()
は通常、区切り文字は「,」(カンマ)として扱います。
他の区切り文字のファイルを読み込みたい場合は、引数に delimiter
を指定します。
サンプルとして区切り文字がスペースのCSVファイル kawa_space.csv を読み込みます。
1 2 3 4 5 6 7 8 9 10 | with open('kawa_space.csv', newline='') as f: d_reader = csv.Dictreader(f, delimiter=' ') row_dlist = [row for row in d_reader] pprint(row_dlist, sort_dicts=False) # [{'No': '1', '河川名': '信濃川', '延長(km)': '367'}, # {'No': '2', '河川名': '利根川', '延長(km)': '322'}, # {'No': '3', '河川名': '石狩川', '延長(km)': '268'}, # {'No': '4', '河川名': '天塩川', '延長(km)': '256'}, # {'No': '5', '河川名': '北上川', '延長(km)': '249'}] |
CSVファイルの書き込み(リスト)
CSVファイルの書き込み・出力
CSVファイルの書き込みには csv.writer
クラスの、writerow()
メソッドを使用します。
対象のデータはリストで指定します。
writerオブジェクト.writerow(リスト)
第一引数には open()
関数で開いたファイルオブジェクトを指定します。
新規作成の場合は、open()
の第一引数に新規ファイルのパス、第二引数の書き込みモードに 'w'
を指定します。
またWindows環境の場合は newline = ''
を指定する必要があります。デフォルトは None
ですが、これだと1行空白が空いてしまいます。
1 2 3 4 | with open('kawa_write.csv', 'w', newline='') as f: writer = csv.writer(f) writer.writerow(['No', '河川名', '延長(km)']) writer.writerow(['1', '信濃川', 367]) |
以下のようなファイルが出力されます。
既存ファイルに対して書き込みモードを 'w'
とすると上書きされます。
既存ファイルに追記したい場合は、書き込みモードに 'a'
を指定します。
1 2 3 | with open('kawa_write.csv', 'a', newline='') as f: writer = csv.writer(f) writer.writerow(['2', '利根川', 322]) |
以下のように3行目が追加されます。
二次元配列を書き込み
二次元配列のデータを、CSVファイルに複数行で書き込むには、writerows()
メソッドを使用します。
writerオブジェクト.writerows(リスト)
1 2 3 4 5 6 7 8 9 10 | kawa_list = [['No', '河川名', '延長(km)'], ['1', '信濃川', 367], ['2', '利根川', 322], ['3', '石狩川', 268], ['4', '天塩川', 256], ['5', '北上川', 249]] with open('kawa_writerows.csv', 'w', newline='') as f: writer = csv.writer(f) writer.writerows(kawa_list) |
以下のファイルが出力されます。
区切り文字を指定
デフォルトではカンマ区切りのファイルが出力されます。
区切り文字を指定したい場合は、引数 delimiter
で指定します。
1 2 3 | with open('kawa_writerows.csv', 'w', newline='') as f: writer = csv.writer(f, delimiter=' ') writer.writerows(kawa_list) |
引用符を追加する
書き込むデータに区切り文字を含む要素は、引用符で囲まれて書き込まれます。
1 2 3 4 5 | kawa_list_add = [['6', '阿武隈川', 239], ['7', '最上川, 木曽川', 229]] with open('kawa_writerows.csv', 'a', newline='') as f: writer = csv.writer(f) writer.writerows(kawa_list_add) |
引数 quoting
で引用符の追加を指定する事ができます。デフォルトは quoting=csv.QUOTE_MINIMAL
で、上の例のように、区切り文字を含む要素のみが引用符 ""
で囲まれます。
全ての要素を引用符で囲む場合は quoting=csv.QUOTE_ALL
、数値以外を引用符で囲む場合は quoting=csv.QUOTE_NONNUMERIC
を指定します。
また、引用符はデフォルトでは ""
(ダブルクオーテーション)ですが、quotechar
で他の文字を指定可能です。
1 2 3 4 5 6 7 8 9 10 11 | kawa_list = [['No', '河川名', '延長(km)'], ['1', '信濃川', 367], ['2', '利根川', 322], ['3', '石狩川', 268], ['4', '天塩川', 256], ['5', '北上川', 249], ['6', '阿武隈川', 239], ['7', '最上川, 木曽川', 229]] with open('kawa_write_quote.csv', 'w', newline='') as f: writer = csv.writer(f, quoting=csv.QUOTE_NONNUMERIC, quotechar="'") writer.writerows(kawa_list) |
CSVファイルの書き込み(辞書)
CSVファイルの書き込み・出力
辞書データを書き込むには、csv.DictWriter()
クラスを使用します。
writeheader()
メソッドで、fieldnames
をヘッダーとして書き込ます。
行の書き込みは writerow()
で、引数に辞書を指定します。
writerオブジェクト.writeheader()
writerオブジェクト.writerow(辞書データ)
1 2 3 4 5 6 7 | with open('kawa_write_dict.csv', 'w', newline='') as f: header = ['No', '河川名', '延長(km)'] writer = csv.DictWriter(f, fieldnames=header) writer.writeheader() writer.writerow({'No': '1', '河川名': '信濃川', '延長(km)': 367.0}) writer.writerow({'No': '2', '河川名': '利根川', '延長(km)': 322.0}) writer.writerow({'No': '3', '河川名': '石狩川', '延長(km)': 268.0}) |
既存ファイルに追記したい場合は、書き込みモードに 'a'
を指定します。
ヘッダは既に書き込まれているので、writer.writeheader()
は不要です。
1 2 3 4 5 | with open('kawa_write_dict.csv', 'a', newline='') as f: header = ['No', '河川名', '延長(km)'] writer = csv.DictWriter(f, header) writer.writerow({'No': '4', '河川名': '天塩川', '延長 (km)': 256.0}) writer.writerow({'No': '5', '河川名': '北上川', '延長 (km)': 249.0}) |
二次元配列を書き込み
二次元配列の辞書データを、CSVファイルに複数行で書き込むには、リストの場合と同様にwriterows()
メソッドを使用します。
writerオブジェクト.writeheader()
writerオブジェクト.writerow(辞書データ)
1 2 3 4 5 6 7 8 9 10 11 | kawa_dlist =[{'No': '1', '河川名': '信濃川', '延長(km)': 367.0}, {'No': '2', '河川名': '利根川', '延長(km)': 322.0}, {'No': '3', '河川名': '石狩川', '延長(km)': 268.0}, {'No': '4', '河川名': '天塩川', '延長(km)': 256.0}, {'No': '5', '河川名': '北上川', '延長(km)': 249.0}] with open('kawa_writerows_dict.csv', 'w', newline='') as f: header = ['No', '河川名', '延長(km)'] writer = csv.DictWriter(f, fieldnames=header) writer.writeheader() writer.writerows(kawa_dlist) |
標準モジュールの csv
でCSVファイルの読み込み・書き込みを行う方法を解説しました。
・関連記事:pandasでCSVファイルを読み込む方法(read_csv)
・関連記事:pandasでExcelファイルの読み込み(read_excel)
・関連記事:pandasでExcelファイルの書き込み(to_excel)