この記事ではPythonでのCSVファイルの操作について解説します。
Pythonのcsvモジュールは、アプリケーションから取り出したcsvファイルを使って独自の集計やデータの移行などさまざまな場所で活用することができます。
csv モジュールとは?
csv
はPythonでCSVファイルを扱えるモジュールのことです。使用するためにはimport
する必要があります。
CSVファイルとは、「Comma Separated Values」の略称を指します。名前の通り、値や項目を,
(カンマ)で区切って書かれたファイル・データのことを言います。ファイルの拡張子は.csv
で、互換性が高い特徴があり、様々なソフトに取り込み・使用ができます。
以下がCSVファイル形式で書いたファイルです。
学校名, 学年, 名前, 専攻カリキュラム, 成績
Envader, 1st, Bob, Programming, A
Envader, 2nd, Alisa, UI/UX, B
Envader, 1st, Mike, Programming, B
Envader, 2nd, Adam, DataScience, S
Envader, 2nd, Lisa, Front-end, A
上記のファイルの拡張子を.csv
にし、ファイルを読み込むと以下のようになります。
ファイル操作
Pythonにおけるcsvファイルの取り扱いを説明します。
-
with
本記事は
with
を使用し、ファイル操作を行います。with
はファイルを一定期間操作する構文で、ファイルを自動でクローズするという特徴があります。with
構文は、open()
と組み合わせて以下のように記述します。with open(<ファイル名>, mode=<"モード">, encoding="文字コード") as <別名>:
-
open()
open()
の引数のファイル指定は必須です。モードと文字コードは必要に応じて使用・使い分けします。また、as
でファイル操作を行うファイルオブジェクトに別名を付けることができ、その別名はファイルをクローズするまでのスコープで使用できます。モードはいくつかの種類とそれぞれの特徴がありますので表にまとめました。
mode 詳細 特徴 r 読み込み用 デフォルト値 w 書き込み用 x 新規作成 + 書き込み用 既にファイルがあるとエラーになる a 追記用 b バイナリモード r, w, aと一緒に指定が必要 t テキストモード r, w, aと一緒に指定が必要 + 更新用 r, w, a, xと一緒に指定が必要
csvモジュールの主な関数
今回紹介するcsvモジュールの関数を表にまとめました。
関数 | 詳細 | 特徴 |
---|---|---|
csv.reader | ファイルの読み込み | リスト型を返す |
csv.Dictreader | ファイルの読み込み | 辞書型を返す |
csv.writer | ファイルの書き込み | リスト型を書き込む |
csv.DictWriter | ファイルの書き込み | 辞書型を書き込む |
CSVモジュールを使った読み込み
ここから、実際にcsvモジュールを使ってCSVファイルを操作していきます。まずはCSVファイルの読み込み操作から行います。
csv.reader
csv.reader
は、CSVファイルの各行をリストとして読み込みます。
-
基本的な使い方
以下のCSVファイル(
sample.csv
)を読み込みます。学校名,学年,名前,専攻カリキュラム,成績 Envader,1st,Bob,Programming,A Envader,2nd,Alisa,UI/UX,B
import csv with open("sample.csv") as file_object: reader_object = csv.reader(file_object) # ① print(reader_object) # ② for row in reader_object: print(row) # 出力結果①: <_csv.reader object at 0x1029fc040> # 出力結果②: # ['学校名', '学年', '名前', '専攻カリキュラム', '成績'] # ['Envader', '1st', 'Bob', 'Programming', 'A'] # ['Envader', '2nd', 'Alisa', 'UI/UX', 'B']
出力結果①は、
open()
で開いたファイルオブジェクトをcsv.reader()
に渡して出力した結果です。csv.reader
でファイルオブジェクトを読み込むとreaderオブジェクトが返されます。csv.readerが返したreaderオブジェクトはイテレータプロトコルに対応します。そのため、②のようにfor文で行ごとに取り出すことができます。
-
二次元配列として取得
以下のCSVファイル(
sample.csv
)を読み込み、二次元リストで出力します。1,2,3,4 5,6,7,8
import csv with open("sample.csv") as file_object: reader_object = csv.reader(file_object) # リスト内包表記を使用して二次元リストを取得 sample_list = [row for row in reader_object] print(sample_list) # 出力結果: # [['1', '2', '3', '4'], ['5', '6', '7', '8']]
行・要素・列の取得
以下のCSVファイル(sample.csv
)の、「行・要素・列」を取得します。
1,2,3,4
5,6,7,8
9,10,11,12
13,14,15,16
17,18,19,20
-
行の取得
行の取得は、二次元リストに対してインデックス指定、またはスライスを行います。
import csv with open("sample.csv") as file_object: reader_object = csv.reader(file_object) sample_list = [row for row in reader_object] # ①index指定 print(sample_list[0]) print(sample_list[-1]) # 出力結果: # ['1', '2', '3', '4'] # ['9', '10', '11', '12'] # ②スライス print(sample_list[3:]) print(sample_list[0:2]) # 出力結果: # [['13', '14', '15', '16'], ['17', '18', '19', '20']] # [['1', '2', '3', '4'], ['5', '6', '7', '8']]
-
要素の取得
要素の取得は、二次元リストに対してインデックス指定を行います。インデックス指定は①のように、「リスト内の何番目のリスト + 何番目の要素」を指定します。
import csv with open("sample.csv") as file_object: reader_object = csv.reader(file_object) sample_list = [row for row in reader_object] print(sample_list[0][0]) print(sample_list[2][3]) # 出力結果: # 1 # 12
-
列の取得
列の取得方法は二種類あります。一つ目は、二次元リストの行と列を入れ替える(転置)方法です。
import csv import pprint # コード整形用 with open("sample.csv") as file_object: reader_object = csv.reader(file_object) sample_list = [row for row in reader_object] # ①行と列を入れ替える(転置) columns_list = [list(x) for x in zip(*sample_list)] pprint.pprint(columns_list) # 出力結果: # [['1', '5', '9', '13', '17'], # ['2', '6', '10', '14', '18'], # ['3', '7', '11', '15', '19'], # ['4', '8', '12', '16', '20']] # ②特定の列を取得 print(columns_list[0]) print(columns_list[3]) # 出力結果: # ['1', '5', '9', '13', '17'] # ['4', '8', '12', '16', '20']
2つ目は、readerオブジェクトから行を取り出し、その行の特定のインデックスを繰り返し取得することで列として取得する方法です。
import csv with open("sample.csv") as file_object: reader_object = csv.reader(file_object) # ①特定の列を取得する sample_list1 = [row[0] for row in reader_object] print(sample_list1) # 出力結果: ['1', '5', '9', '13', '17'] # ②違う列を取得するためにはもう一度ファイル操作から行う必要がある with open("sample.csv") as file_object: reader_object = csv.reader(file_object) sample_list2 = [row[3] for row in reader_object] print(sample_list2) # 出力結果: ['4', '8', '12', '16', '20']
上記の①と②を見ての通り、最初に取得した列とは違う列を取得するためには、再度CSVファイルをオープンする所から始める必要があります。
csvモジュールを用いて列を取得する方法はどちらも多少の手間がかかります。ここでは紹介しませんが、ライブラリのNumpyやpandasを使用すると、もっと簡単に多次元の操作をすることが可能です。
文字列を数値に変換
CSVファイルから取り出した値はデフォルトで文字列型です。そのため、CSVファイルからデータを取得し、そのデータを更に加工するためには数値に変換する必要があります。
今回は取り出した文字列型をint型とfloat型に変換する方法を紹介します。
-
int型に変換
以下のCSVファイル(
sample.csv
)を使用し、int型に変換します。1, 2, 3, 4 5, 6, 7, 8
import csv with open("sample.csv") as file_object: reader_object = csv.reader(file_object) # ①二次元リストを取得 sample_list = [row for row in reader_object] # ②取り出した要素の型を確認する print(sample_list[0][0]) print(type(sample_list[0][0])) # 出力結果: # 1 # <class 'str'> # ③二次元リストの最初の行をint型に変換する int_list = [int(i) for i in sample_list[0]] print(int_list) print(type(int_list[0])) # 出力結果: # [1, 2, 3, 4] # <class 'int'> # ④二次元リストを一気にint型に変換する print([[int(i) for i in row] for row in sample_list]) # 出力結果: # [[1, 2, 3, 4], [5, 6, 7, 8]]
-
float型に変換
float型への変換は二種類のやり方があります。まずはint型に変換した時と同様に行います。
以下のCSVファイル(
sample.csv
)を使用します。1.2,1.2,1.3,1.4 1.5,1.6,1.7,1.8
import csv with open("sample.csv") as file_object: reader_object = csv.reader(file_object) sample_list = [row for row in reader_object] # ①CSVファイルの最初の行をfloat型に変換する float_list = [float(i) for i in sample_list[0]] print(float_list) print(type(float_list[0])) # 出力結果: # [1.2, 1.2, 1.3, 1.4] # <class 'float'> # ②二次元リストを一気にfloat型に変換する print([[float(i) for i in row] for row in sample_list]) # 出力結果: # [[1.2, 1.2, 1.3, 1.4], [1.5, 1.6, 1.7, 1.8]]
もう一つのやり方は、ファイルオブジェクトから読む込む時点でfloat型へ変換します。
import csv with open("sample.csv") as file_object: # ①csv.readerの引数にquoting=csv.QUOTE_NONNUMERICを追加 reader_object = csv.reader(file_object, quoting=csv.QUOTE_NONNUMERIC) sample_list = [row for row in reader_object] # ②要素の型を確認する print(sample_list[0][0]) print(type(sample_list[0][0])) # 出力結果: # 1.1 # <class 'float'>
①のように、
QUOTE_NONNUMERIC
を指定するとファイルオブジェクトから読み込む時点で、全てのフィールドをfloat型に変換することができます。こちらのやり方の方が簡単にfloat型に変換することができます。
区切り文字の指定
csv.reader()
のデフォルトの区切り文字は,
(カンマ)です。デフォルト以外を指定するためには、csv.reader()
の引数のdelimiter
に任意の区切り文字を指定します。
以下の空白で区切られたCSVファイル(sample.csv
)を使用し、区切り文字を空白に指定して読み込みます。
1 2 3 4
5 6 7 8
import csv
with open("sample.csv") as file_object:
# ①区切り文字を空白に指定
reader_object = csv.reader(file_object, delimiter=" ")
sample_list = [row for row in reader_object]
print(sample_list)
# 出力結果: [['1', '2', '3', '4'], ['5', '6', '7', '8']]
引用符の扱い
CSVファイルには引用符が入っている時があります。その場合、csv.reader
が引用符をどう処理するのかを見てみます。
引用符の”
(ダブルクオーテーション)が使われている以下のCSVファイル(sample.csv
)を使用します。
商品 単価 数量
A商品 500 1
B商品 900 3
"Python csvの本" 1500 1
import csv
with open("sample.csv", encoding="UTF-8") as file_object:
reader_object = csv.reader(file_object, delimiter=" ")
for row in reader_object:
print(row)
# 出力結果:
# ['商品', '単価', '数量']
# ['A商品', '500', '1']
# ['B商品', '900', '3']
# ①['Python csvの本', '1500', '1']
出力結果①を見て頂きたいのですが、CSVファイルにあった”
が出力されていません。このように、csv.reader
はデフォルトで引用符を無視します。基本的にはこの動作で問題ないですが、この引用符に対しての処理を行って欲しくない場合は以下のように行います。
import csv
with open("sample.csv", encoding="UTF-8") as file_object:
# ①csv.readerの引数にquoting=csv.QUOTE_NONEを指定
reader_object = csv.reader(file_object, delimiter=" ", quoting=csv.QUOTE_NONE)
for row in reader_object:
print(row)
# 出力結果:
# ['商品', '単価', '数量']
# ['A商品', '500', '1']
# ['B商品', '900', '3']
# ②['"Python', 'csvの本"', '1500', '1']
改行を含むファイルの扱い
改行を含んだCSVファイルを読み込む場合、open()
の引数にnewline=’’
を指定することが推奨されています。これはOSによる改行コードの扱いの違いを同じように処理できるためです。改行に関するPythonの公式ドキュメントの説明を以下に引用します。
newline=''
が指定されない場合、クォートされたフィールド内の改行は適切に解釈されず、書き込み時に\r\n
を行末に用いる処理系では余分な\r
が追加されてしまいます。csv モジュールは独自(universal) の改行処理を行うため、newline=''
を指定することは常に安全です。(参照:csv --- CSV ファイルの読み書き)
headerを含むファイルの扱い
header(見出し行・見出し列)を含んだCSVファイルの「数値データだけ」を使いたいという場合は多いと思います。以下のようなheaderを含んだCSVファイル(sample.csv
)から、header以外のデータだけを抽出する方法を紹介します。
,Bob,Lisa,Mike,Alisa
Math,70,30,80,60
English,90,85,50,70
Science,80,100,50,80
Japanese,80,70,90,85
import csv
import pprint # データ整形のために使用
with open("sample.csv") as file_object:
reader_object = csv.reader(file_object)
# ①headerを含む全てのCSVファイルを取得
sample_list = [row for row in reader_object]
pprint.pprint(sample_list)
# 出力結果:
# [['', 'Bob', 'Lisa', 'Mike', 'Alisa'],
# ['Math', '70', '30', '80', '60'],
# ['English', '90', '85', '50', '70'],
# ['Science', '80', '100', '50', '80'],
# ['Japanese', '80', '70', '90', '85']]
# ② ①から数値データ部分のみを取得する
pprint.pprint([row [1:] for row in sample_list[1:]])
# 出力結果:
# [['70', '30', '80', '60'],
# ['90', '85', '50', '70'],
# ['80', '100', '50', '80'],
# ['80', '70', '90', '85']]
# ③ ①から数値データ部分を抽出する時点でint型に変換する
print([[int(i) for i in row[1:]] for row in sample_list[1:]])
# 出力結果:
# [[70, 30, 80, 60], [90, 85, 50, 70], [80, 100, 50, 80], [80, 70, 90, 85]]
header以外を抽出したい、などの細かい条件に合わせたファイル操作はpandasを使用するともっと簡単に行うことができます。
csv. DictReader
Pythonのcsvモジュールに用意されたファイルの読み込みには、csv.reader
以外にcsv.DictReader
があります。csv.reader
はCSVファイルをリストとして読み込みますが、csv.DictReader
はCSVファイルを辞書として読み込みます。
-
基本的な使い方
以下のCSVファイル(
sample.csv
)を使用します。A,B,C,D 1,2,3,4 5,6,7,8
import csv import pprint with open("sample.csv") as file_object: # ① dict_reader_object = csv.DictReader(file_object) # ② sample_dict = [row for row in dict_reader_object] # ③dict型を返す pprint.pprint(sample_dict) # 出力結果: # [{'A': '1', 'B': '2', 'C': '3', 'D': '4'}, # {'A': '5', 'B': '6', 'C': '7', 'D': '8'}]
①、②のように、基本的な使い方は
csv.reader
と同じです。また、行・要素・列もcsv.reader
で紹介した方法で取得できます。③の出力結果のように、CSVファイルのフィールド(列)の最初の値がキーとなり、二番目以降の値がキーに対応する形で出力されます。
また、
csv.DictReader
の返す型はPythonバージョン3.8からdict型を返すようになりました。(参照: csv --- CSV ファイルの読み書き csv.DictReader)
header(見出し行)がない場合
csv.DictReader
の特徴は見出し行が辞書型のキーとなる点です。もし、CSVファイルに見出し行がない場合、どう出力されるかを以下のCSVファイル(sample.csv
)を使用して見てみます。
1,2,3,4
5,6,7,8
9,10,11,12
import csv
import pprint
with open("sample.csv") as file_object:
dict_reader_object = csv.DictReader(file_object)
sample_dict = [row for row in dict_reader_object]
# ①
pprint.pprint(sample_dict)
# 出力結果:
# [{'1': '5', '2': '6', '3': '7', '4': '8'},
# {'1': '9', '2': '10', '3': '11', '4': '12'}]
csv.DictReader
は、デフォルトでは「CSVファイルのフィールドの最初の値」をキーとします。もし見出し行がないCSVファイルを読み込んだ場合、①の出力結果のように関連のないキーと値のセットになってしまいます。
csv.DictReader
の引数にfieldnames
を指定すると、任意の値を見出し行として設定し、その値を辞書のキーとして設定することができます。
import csv
import pprint
with open("sample.csv") as file_object:
# ②見出し行にA,B,C,Dを指定する
dict_reader_object = csv.DictReader(file_object, fieldnames=["A", "B", "C", "D"])
sample_dict = [row for row in dict_reader_object]
# ③
pprint.pprint(sample_dict)
# 出力結果:
# [{'A': '1', 'B': '2', 'C': '3', 'D': '4'},
# {'A': '5', 'B': '6', 'C': '7', 'D': '8'},
# {'A': '9', 'B': '10', 'C': '11', 'D': '12'}]
header(見出し列)の削除方法
今度は見出し列があるCSVファイルを読み込んだ場合を、以下のCSVファイル(sample.csv
)を使用して見てみます。
A,B,C,D
Bob,80,70,90,100
Lisa,90,100,70,80
Alisa,70,80,100,100
import csv
import pprint
with open("sample.csv") as file_object:
dict_reader_object = csv.DictReader(file_object)
sample_dict = [row for row in dict_reader_object]
# ①見出し列を含めた出力結果
pprint.pprint(sample_dict)
# 出力結果:
# [{'': 'Bob', 'A': '80', 'B': '70', 'C': '90', 'D': '100'},
# {'': 'Lisa', 'A': '90', 'B': '100', 'C': '70', 'D': '80'},
# {'': 'Alisa', 'A': '70', 'B': '80', 'C': '100', 'D': '100'}]
①の出力結果のように、csv.DictReader
は、見出し列に対しては特別な処理を行いません。見出し列を除外したい場合はpop()
、popitem()
、del
などを使用します。今回はpop()
を使用し、見出し列を削除します。
import csv
import pprint
with open("sample.csv") as file_object:
dict_reader_object = csv.DictReader(file_object)
sample_dict = [row for row in dict_reader_object]
# ②見出し列の削除
print([hc.pop("") for hc in sample_dict])
# 出力結果: ['Bob', 'Lisa', 'Alisa']
# ③見出し列の削除後の辞書を出力する
pprint.pprint(sample_dict)
# 出力結果:
# [{'A': '80', 'B': '70', 'C': '90', 'D': '100'},
# {'A': '90', 'B': '100', 'C': '70', 'D': '80'},
# {'A': '70', 'B': '80', 'C': '100', 'D': '100'}]
csvモジュールを使った書き込み
ここからはcsvモジュールを使ったCSVファイルの書き込み操作を行なっていきます。
csv.writer
csv.writer
はCSVファイルにリストとして書き込みます。
-
基本的な使い方
CSVファイルを新規作成して、そこに書き込みます。新規作成の場合、
open()
のモードにw
を指定します。import csv # ①ここから書き込み with open("sample.csv", "w") as file_object: writer_object = csv.writer(file_object) writer_object.writerow([1, 2, 3]) writer_object.writerow(["A", "B", "C"]) # ②書き込まれた内容の確認 with open("sample.csv") as file_object: print(file_object.read()) # ③出力結果: # 1,2,3 # A,B,C
①の書き込み処理を説明します。
新規作成モードでCSVファイルを開き、そのファイルオブジェクトを
csv.writer
に渡すとwriterオブジェクトが取得できます。このwriterオブジェクトに対して、csv.writer
に用意されているwriterow()
を使用すると、引数に渡した内容を一行ずつ書き込むことができます。 -
既存ファイルに追記する場合
追記する場合は
open()
のモードにa
に指定します。先ほど新規作成したCSVファイル(sample.csv
)に追記します。import csv # ①追記モードで書き込み with open("sample.csv", "a") as file_object: writer_object = csv.writer(file_object) writer_object.writerow([4, 5, 6]) writer_object.writerow(["D", "E", "F"]) # ②書き込まれた内容の確認 with open("sample.csv") as file_object: print(file_object.read()) # ③出力結果: 末尾に追加される # 1,2,3 # A,B,C # 4,5,6 # D,E,F
-
二次元リストの書き込み
csv.writer
のwriterows()
を使用すると、二次元リスト(複数行)を一度に書き込むことができます。import csv # ①書き込む二次元リストを用意 write_list = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]] # ②ここから書き込み with open("sample.csv", "w") as file_object: writer_object = csv.writer(file_object) writer_object.writerows(write_list) # ③書き込まれた内容の確認 with open("sample.csv") as file_object: print(file_object.read()) # ④出力結果: # 1,2,3,4 # 5,6,7,8 # 9,10,11,12
区切り文字の指定
csv.writer
の区切り文字のデフォルトは、,
(カンマ)区切りで書き込まれます。カンマ以外で書き込みたい場合はcsv.writer
の引数にdelimiter
と任意の区切り文字を指定します。
import csv
import pprint
# ①書き込む二次元リストを用意
write_list = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
# ②ここから書き込み
with open("sample.csv", "w") as file_object:
# ③空白区切りを指定
writer_object = csv.writer(file_object, delimiter=" ")
writer_object.writerows(write_list)
# ④ここから読み込み(書き込まれたことの確認)
with open("sample.csv") as file_object:
reader_object = csv.reader(file_object)
sample_list = [row for row in reader_object]
pprint.pprint(sample_list, width=40)
# ⑤出力結果:
# [['1 2 3 4'],
# ['5 6 7 8'],
# ['9 10 11 12']]
引用符の扱い
csv.writer
で引用符を含んだデータを書き込んだ場合、どのようにCSVファイルに書き込まれるかを見てましょう。
import csv
# ①書き込む二次元リストを用意
write_list = [[1, 2, 3], ["A", "B", "CD"], ["E,F,G", "H", "I"]]
# ②ここから書き込み
with open("sample.csv", "w") as file_object:
writer_object = csv.writer(file_object)
writer_object.writerows(write_list)
# ③ここから読み込み(書き込まれたことの確認)
with open("sample.csv") as file_object:
print(file_object.read())
# ④出力結果:
# 1,2,3
# A,B,CD
# "E,F,G",H,I
④の出力結果のように、デフォルトでは「区切り文字のような特別な文字を含む要素のみ」(”E,F,G”
だけ)が”
(ダブルクオーテーション)で囲まれています。
csv.writer
の引用符は、引数quoting
で制御できます。quoting
の指定はいくつか種類があるので表にまとめました。
quoting= | 引用符の扱い | 特徴 |
---|---|---|
csv.QUOTE_MINIMAL | 特別な文字を含む要素のみを引用符で囲む | デフォルト |
csv.QUOTE_ALL | 全ての要素を引用符で囲む | |
quoting.QUOTE_NONNUMERIC | 数値でない要素が引用符で囲まれる | |
csv.QUOTE_NONE | どの要素も引用符で囲まれない | escapecharの文字指定が必要 |
また、書き込み時の引用符をデフォルトの”
(ダブルクオーテーション)から変更したい場合は、引数quotechar
を指定します。
改行を加えて書き込む場合
csv.writer
を使用して任意の場所に改行を入れたい時の方法と、それがCSVファイルにどう書き込まれるかを見てみましょう。
import csv
# ①書き込む二次元リストを用意(改行コードを含む)
write_list = [[1, 2, 3], ["A\n", "B", "C"], [4, "\n5", "6"]]
# ②ここから書き込み
with open("sample.csv", "w", newline='') as file_object:
writer_object = csv.writer(file_object)
writer_object.writerows(write_list)
# ③ここから読み込み(書き込まれたことの確認)
with open("sample.csv") as file_object:
print(file_object.read())
# ④出力結果:
# 1,2,3
# "A
# ",B,C
# 4,"
# 5",6
指定の箇所で改行処理をして書き込みを行いたい場合、①のように要素の前後に改行コードを記述し、要素と改行コードごと引用符で囲みます。
読み込みの際に紹介した理由と同様に、改行を扱う際は②のようにopen()
の引数newline
を’’
としておいた方が安全です。
出力結果は④のように、改行コードを含んだ要素は引用符で囲まれてCSVファイルに書き込まれます。
headerなどを加える場合
csv.writer
にはheader(見出し行・見出し列の両方)を加えて出力する特別な機能が備わっていません。そのため、見出し行・見出し列を加えたい場合は、そのための処理を自分で行う必要があります。
-
見出し行を加える場合
新規作成で見出し行を加えたい場合は、一行目に見出し行を書き込むだけなので簡単です。逆に、既存のファイルに見出し行を加える場合は少し手間がかかります。(追記モードが末尾に文字を挿入するため)
今回は、以下のCSVファイル(
sample.csv
)を使って既存のファイルに追記する方法を紹介します。import csv import pprint # ①見出し行を用意しておく write_header = ["A", "B", "C", "D", "E"] # ②まずは既存のファイルを読み込んで2次元リストに格納する with open("sample.csv") as file_object: reader_object = csv.reader(file_object) sample_list = [row for row in reader_object] # ③2次元リストの確認 pprint.pprint(sample_list) # [['1', '2', '3', '4', '5'], # ['6', '7', '8', '9', '10'], # ['11', '12', '13', '14', '15']] # ④既存のファイルを上書きする形(新規作成)で開く with open("sample.csv", "w") as file_object: writer_object = csv.writer(file_object) # ⑤見出し行->既存のファイルデータの順で書き込む writer_object.writerow(write_header) writer_object.writerows(sample_list) with open("sample.csv") as file_object: print(file_object.read()) # ⑥出力結果: 最終的なsample.csvの中を確認 # A,B,C,D,E # 1,2,3,4,5 # 6,7,8,9,10 # 11,12,13,14,15
-
見出し列を加える場合
見出し列を加える場合は、各行の先頭に要素を追加する処理が必要です。
以下のCSVファイル(
sample.csv
)に見出し列を追加します。'',Bob,Lisa,Mike,Alisa 70,30,80,60 90,85,50,70 80,100,50,80 80,70,90,85
import csv import pprint # ①見出し列を用意する write_index = ["Math","Japanese","Science","English"] # ②既存のファイルを読み込んで2次元リストに格納する with open("sample.csv") as file_object: reader_object = csv.reader(file_object) sample_list = [row for row in reader_object] # ③2次元リストの確認 pprint.pprint(sample_list) # [["''", 'Bob', 'Lisa', 'Mike', 'Alisa'], # ['70', '30', '80', '60'], # ['90', '85', '50', '70'], # ['80', '100', '50', '80'], # ['80', '70', '90', '85']] # ④既存のファイルを上書きする形で、新規作成で開く with open("sample.csv", "w") as file_object: writer_object = csv.writer(file_object) # ⑤見出し行を書き込む writer_object.writerow(sample_list[0]) # ⑥見出し列を先頭に加えながら、残りの2次元リストを書き込む for i, row in zip(write_index, sample_list[1:]): writer_object.writerow([i] + row) with open("sample.csv") as file_object: print(file_object.read()) # ⑦出力結果: 最終的なsample.csvの中を確認 # '',Bob,Lisa,Mike,Alisa # Math,70,30,80,60 # Japanese,90,85,50,70 # Science,80,100,50,80 # English,80,70,90,85
csv.writer
を使用して見出し行・見出し列を追加するためには多少の手間を要します。こういった処理の場合は、pandasを使用するともっと簡単に行うことができます。
csv. DictWriter
Pythonのcsvモジュールに用意されたファイルの書き込みには、csv.writer
以外にcsv.DictWriter
があります。csv.writer
はCSVファイルをリストとして書き込みますが、csv.DictWriter
はCSVファイルを辞書として書き込みます。
-
基本的な使い方
import csv with open("sample.csv", "w") as file_object: # ①csv.DictWriterの第2引数にリストを指定する dw_object = csv.DictWriter(file_object, ["A", "B", "C"]) # ②writeheader()を実行すると①で指定したリストの要素がヘッダーとして書き込まれる dw_object.writeheader() # ③writerow()で一行ずつ書き込む dw_object.writerow({"A": 1, "B": 2, "C": 3}) # ④キーがCの要素を記述しない dw_object.writerow({"A": 4, "B": 5}) # ⑤エラーになるパターン dw_object.writerow({"D": 4, "B": 5, "C": 6}) dw_object.writerow({"": 4, "B": 5, "C": 6}) # ⑥ここから読み込み(書き込まれたことの確認) with open("sample.csv") as file_object: print(file_object.read()) # ⑦: ①〜④までの出力結果 # A,B,C # 1,2,3 # 4,5,
①では、
csv.DictWriter
の第一引数に「開いたファイルのオブジェクト」、第二引数に「辞書のキーのリスト」を指定します。こうするとDictWriterオブジェクトが取得できます。書き込む際は④のようにキーが存在しない辞書を書き込むことはできますが、⑤のようにヘッダーで設定したキーと違う値を指定したり、キーを省略するとエラーになります。
-
複数の辞書を一度に書き込む
import csv dict1 = {"A": 1, "B": 2, "C": 3} dict2 = {"A": 4, "B": 5, "C": 6} dict3 = {"A": 7, "C": 9} with open("sample.csv", "w") as file_object: dw_object = csv.DictWriter(file_object, ["A", "B", "C"]) dw_object.writeheader() # ① dw_object.writerows([dict1, dict2, dict3]) # ②ここから読み込み(書き込まれたことの確認) with open("sample.csv") as file_object: print(file_object.read()) # ③出力結果: # A,B,C # 1,2,3 # 4,5,6 # 7,,9
①のように、writerows()の引数には複数の辞書を指定することができます。辞書を指定する際にはリストで渡す必要があります。
辞書の特定のキーを書き込みたくない場合
例えば、書き込みたい辞書にはA, B, C
のキーが存在するが、A, C
だけ書き込みたいといった場合です。書き込みたい辞書の特定のキーだけは除外して書き込む方法を紹介します。
import csv
dict1 = {"A": 1, "B": 2, "C": 3}
dict2 = {"A": 4, "B": 5, "C": 6}
dict3 = {"A": 7, "B": 8, "C": 9}
with open("sample.csv", "w") as file_object:
# ①第二引数には書き込みたいキー
# ②引数extrasactionをignoreに指定
dw_object = csv.DictWriter(file_object, ["A", "C"], extrasaction="raise")
# ③エラーになるパターン
# dw_object = csv.DictWriter(file_object, ["A", "C"])
dw_object.writeheader()
dw_object.writerows([dict1, dict2, dict3])
# ④ここから読み込み(書き込まれたことの確認)
with open("sample.csv") as file_object:
print(file_object.read())
# ⑤出力結果:
# A,C
# 1,3
# 4,6
# 7,9
②のように、csv.DictWriter
に引数extrasaction="ignore"
を指定すると、ヘッダーで指定されていないキーを無視することができます。
デフォルトでは引数extrasaction
はraise
が指定されているため、③のように記述するとValueError
になります。
まとめ
Pythonのcsvモジュールを使用したCSVファイルの読み書きを解説しました。
csvモジュールは、基本的なCSVファイルの読み書きは比較的簡単に行えます。しかし、複雑な配列処理をしてから読み書きを行おうとすると、手間を要する場合があります。そういった場合は、ライブラリのNumpy、pandasの使用を検討しましょう。
【番外編】USBも知らなかった私が独学でプログラミングを勉強してGAFAに入社するまでの話
プログラミング塾に半年通えば、一人前になれると思っているあなた。それ、勘違いですよ。「なぜ間違いなの?」「正しい勉強法とは何なの?」ITを学び始める全ての人に知って欲しい。そう思って書きました。是非読んでみてください。
「フリーランスエンジニア」
近年やっと世間に浸透した言葉だ。ひと昔まえ、終身雇用は当たり前で、大企業に就職することは一種のステータスだった。しかし、そんな時代も終わり「優秀な人材は転職する」ことが当たり前の時代となる。フリーランスエンジニアに高価値が付く現在、ネットを見ると「未経験でも年収400万以上」などと書いてある。これに釣られて、多くの人がフリーランスになろうとITの世界に入ってきている。私もその中の1人だ。数年前、USBも知らない状態からITの世界に没入し、そこから約2年間、毎日勉学を行なった。他人の何十倍も努力した。そして、企業研修やIT塾で数多くの受講生の指導経験も得た。そこで私は、伸びるエンジニアとそうでないエンジニアをたくさん見てきた。そして、稼げるエンジニア、稼げないエンジニアを見てきた。
「成功する人とそうでない人の違いは何か?」
私が出した答えは、「量産型エンジニアか否か」である。今のエンジニア市場には、量産型エンジニアが溢れている!!ここでの量産型エンジニアの定義は以下の通りである。
比較的簡単に学習可能なWebフレームワーク(WordPress, Rails)やPython等の知識はあるが、ITの基本概念を理解していないため、単調な作業しかこなすことができないエンジニアのこと。
多くの人がフリーランスエンジニアを目指す時代に中途半端な知識や技術力でこの世界に飛び込むと返って過酷な労働条件で働くことになる。そこで、エンジニアを目指すあなたがどう学習していくべきかを私の経験を交えて書こうと思った。続きはこちらから、、、、
エンベーダー編集部
エンベーダーは、ITスクールRareTECHのインフラ学習教材として誕生しました。 「遊びながらインフラエンジニアへ」をコンセプトに、インフラへの学習ハードルを下げるツールとして運営されています。
関連記事
2020.02.25
完全未経験からエンジニアを目指す爆速勉強法
USBも知らなかった私が独学でプログラミングを勉強してGAFAに入社するまでの話
- キャリア・学習法
- エンジニア
2024.08.29
プログラミングの基本概念をたとえで理解する
本記事では、プログラミングの基本概念を具体的な日常生活の事象にたとえて説明していきます。これにより、抽象的な概念を視覚的に捉えやすくし、初学者がより理解しやすくなることを目指します。
- プログラミング
- キャリア・学習法
2023.04.16
IaCとは?IaCのメリットやデメリット、Terraformなどの構成管理ツールの特徴を紹介
IaC(Infrastructure as Code)とは、サーバーやネットワーク、ストレージなどをはじめとしたインフラの構成をコード化し、その構成や管理を自動化する手法のことです。
- プログラミング
- インフラエンジニア
2023.08.19
ノーコード・ローコード開発は簡単?稼げる?
そこで今回は、エンジニア初学者の方に向けて、「ノーコード・ローコードは稼げるのか」について解説していきます。
- プログラミング