[解決!Python]CSVファイルから読み込みを行うには(csvモジュール編):解決!Python
pandasやNumpyを使わずに、Pythonに標準で付属するcsvモジュールを使って、CSVファイルから読み込みを行う方法を紹介する。
* 本稿は2021年08月03日に公開された記事をPython 3.12.0で動作確認したものです(確認日:2023年10月04日)。
# csvモジュールを使ってCSVファイルから1行ずつ読み込む
import csv
filename = 'populationdata.csv'
with open(filename, encoding='utf8', newline='') as f:
csvreader = csv.reader(f)
for row in csvreader:
print(row)
# 出力結果:
#['年', '地域コード', '地域', '総人口']
#['1920年', '00000', '全国', '55963053']
# …… 省略 ……
#['2010年', '00000', '全国', '128057352']
#['2020年', '00000', '全国', '126226568']
# タブ区切りの文字を読み込む
filename = 'tabdelimiteddata.tsv'
with open(filename, encoding='utf8', newline='') as f:
csvreader = csv.reader(f, delimiter='\t')
for row in csvreader:
print(row) # 出力結果は省略
# CSVファイルの内容を1つのリストにまとめる
filename = 'populationdata.csv'
with open(filename, encoding='utf8', newline='') as f:
csvreader = csv.reader(f)
content = [row for row in csvreader] # 各年のデータを要素とするリスト
#content = []
#for row in csvreader:
# content.append(row)
print(content)
# 出力結果:
#[['年', '地域コード', '地域', '総人口'], ['1920年', '00000', '全国',
# '55963053'], …… , ['2010年', '00000', '全国', '128057352'], ['2020年',
# '00000', '全国', '126226568']]
# 特定の列のデータ型を変換する
with open(filename, encoding='utf8', newline='') as f:
csvreader = csv.reader(f)
header = next(csvreader) # 見出し行は別扱い
content = [[row[0], row[1], row[2], int(row[3])] for row in csvreader]
content.insert(0, header) # 最後にリストの先頭に見出し行を挿入
print(content)
# 出力結果:
#[['年', '地域コード', '地域', '総人口'], ['1920年', '00000', '全国',
# 55963053], …… , ['2010年', '00000', '全国', 128057352], ['2020年',
# '00000', '全国', 126226568]]
# 数値フィールド以外はシングルクオートで囲まれていることを指示して
# 数値フィールドの値を全て浮動小数点数値に自動的に変換
filename = 'sample.csv'
with open(filename, encoding='utf8', newline='') as f:
csvreader = csv.reader(f, quotechar="'", quoting=csv.QUOTE_NONNUMERIC)
for row in csvreader:
print(row)
# 出力結果
# ['年', '地域コード', '地域', '総人口']
# ['1920年', '00000', '全国', 55963053.0]
# …… 省略 ……
# ['2010年', '00000', '全国', 128057352.0]
# ['2020年', '00000', '全国', 126226568.0]
# CSVファイルの内容から辞書形式のデータを作成
with open(filename, encoding='utf8', newline='') as f:
csvreader = csv.DictReader(f)
content = [row for row in csvreader]
print(content[0])
# 出力結果:
#{'年': '1920年', '地域コード': '00000', '地域': '全国', '総人口': '55963053'}
本稿では、サンプルのCSVファイルの内容として以下を利用する。1行目は見出し行であり、各行には各年/地域コード/地域/総人口の4つのデータが含まれている。
年,地域コード,地域,総人口
1920年,00000,全国,55963053
1930年,00000,全国,64450005
1940年,00000,全国,73075071
1950年,00000,全国,84114574
1960年,00000,全国,94301623
1970年,00000,全国,104665171
1980年,00000,全国,117060396
1990年,00000,全国,123611167
2000年,00000,全国,126925843
2010年,00000,全国,128057352
2020年,00000,全国,126226568
csvモジュールを使ったCSVファイルの読み込み
Pythonにはcsvモジュールが標準で添付されている。これをインポートすることで、CSVファイルの読み込みが行える(ただし、CSVファイルの読み込みをより柔軟な形で行うのであれば、pandasやNumpyを使った方がよいだろう)。
その基本的な手順は次の通り。
- CSVファイルを表すファイルオブジェクトを作成
- そのファイルオブジェクトを、csv.reader関数に渡して、readerオブジェクトを取得
- readerオブジェクトは反復処理可能なので、for文や内包表記などを使って、CSVファイルの内容を読み込む
実際の例を以下に示す。
import csv
filename = 'populationdata.csv'
with open(filename, encoding='utf8', newline='') as f:
csvreader = csv.reader(f)
for row in csvreader:
print(row)
# 出力結果:
#['年', '地域コード', '地域', '総人口']
#['1920年', '00000', '全国', '55963053']
# …… 省略 ……
#['2010年', '00000', '全国', '128057352']
#['2020年', '00000', '全国', '126226568']
この例では、open関数で本稿冒頭に示したサンプルのCSVファイルをオープンし、そのファイルオブジェクトをcsv.reader関数に渡してreaderオブジェクトを取得している。その後は、for文に反復可能オブジェクトとしてreaderオブジェクトを渡して、CSVから1行ずつ読み込みを行い、各行の内容を表示しているだけだ。
なお、open関数のnewline引数には空文字列を渡しているが、これは行末コードの変換を行わないことを意味している。これは、CSVファイルのフィールド要素に改行が含まれている場合に、それらを適切に解釈するために推奨されている。
カンマ「,」ではなく、タブ文字でフィールドが区切られている場合には、csv.reader関数のdelimiter引数に'\t'を渡せば、タブ区切りのファイルからの読み込みも可能だ。
filename = 'tabdelimiteddata.tsv'
with open(filename, encoding='utf8', newline='') as f:
csvreader = csv.reader(f, delimiter='\t')
for row in csvreader:
print(row) # 出力結果は省略
内包表記を使って、CSVファイルの内容を1つのリストに読み込む
CSVから1行ずつ読み込みを行って、逐次的に処理を行うのではなく、CSVファイルの内容を1つのオブジェクトとして読み込んでしまうのであれば、リスト内包表記を使ってリストのリストを作成するのが簡単だ。
以下に例を示す。
filename = 'populationdata.csv'
with open(filename, encoding='utf8', newline='') as f:
csvreader = csv.reader(f)
content = [row for row in csvreader] # 各年のデータを要素とするリスト
#content = []
#for row in csvreader:
# content.append(row)
print(content)
# 出力結果:
#[['年', '地域コード', '地域', '総人口'], ['1920年', '00000', '全国',
# '55963053'], …… , ['2010年', '00000', '全国', '128057352'], ['2020年',
# '00000', '全国', '126226568']]
この例では、open関数を呼び出して得たファイルオブジェクトからreaderオブジェクトを作成したら、内包表記を使って、各行の内容(年/地域コード/地域/総人口)を要素とするリストを作成している(コメントアウトしてあるのは、同様な処理をfor文で書いたものだ)。
フィールドの型を変換する
CSVファイルから読み込んだ内容は通常、全て文字列値となる。そのため、整数値や浮動小数点数値に変換する必要があれば、以下のように内包表記の内部で型変換をするとよい。
例えば、サンプルのCSVファイルでは各行には年/地域コード/地域/総人口の4つのデータが含まれている。最初の3つは文字列が適切だが、最後の総人口は整数値となっていた方が扱いやすいだろう。そこで、以下のようにして最後のフィールドだけ整数値に変換を行える。
filename = 'populationdata.csv'
with open(filename, encoding='utf8', newline='') as f:
csvreader = csv.reader(f)
header = next(csvreader) # 見出し行は特別扱い
content = [[row[0], row[1], row[2], int(row[3])] for row in csvreader]
content.insert(0, header) # 最後にリストの先頭に見出し行を挿入
print(content)
# 出力結果:
#[['年', '地域コード', '地域', '総人口'], ['1920年', '00000', '全国',
# 55963053], …… , ['2010年', '00000', '全国', 128057352], ['2020年',
# '00000', '全国', 126226568]]
この例では、最後のフィールドだけint関数で総人口を整数値に変換している。このとき見出し行には数値データが含まれていないので、特別扱いするのを忘れないようにしよう。
また、CSVファイルのフォーマットによるが、数値以外のデータは全て引用符で囲まれているといった場合には、quotingキーワード引数にcsv.QUOTE_NONNUMERICを指定することで、引用符に囲まれていないデータを全て浮動小数点数値に変換させることも可能だ。以下に例を示す。
filename = 'sample.csv'
with open(filename, encoding='utf8', newline='') as f:
csvreader = csv.reader(f, quotechar="'", quoting=csv.QUOTE_NONNUMERIC)
for row in csvreader:
print(row)
# 出力結果
# ['年', '地域コード', '地域', '総人口']
# ['1920年', '00000', '全国', 55963053.0]
# …… 省略 ……
# ['2010年', '00000', '全国', 128057352.0]
# ['2020年', '00000', '全国', 126226568.0]
ここではquoting引数にquoting=csv.QUOTE_NONNUMERICを指定して数値データ以外のフィールドは全て引用符で囲まれていることと、quotechar引数に"'"を指定してそれらのフィールドはシングルクオートで囲まれていることを指示している。最後のフィールドの値が浮動小数点数値になっている点に注目されたい。
CSVファイルの内容から辞書形式のデータを作成
各行について、列名とその列のデータの組から成るデータを作成したいのであれば、csv.DictReaderクラスを使用する。csv.reader関数と同じように、csv.DictReaderクラスのコンストラクタ呼び出しにファイルオブジェクトを渡し、csv.DictReaderオブジェクトを得たら、それを使って反復処理を行うだけだ。
以下に例を示す。
filename = 'populationdata.csv'
with open(filename, encoding='utf8', newline='') as f:
csvreader = csv.DictReader(f)
content = [row for row in csvreader]
print(content[0])
# 出力結果:
#{'年': '1920年', '地域コード': '00000', '地域': '全国', '総人口': '55963053'}
ここで使用しているサンプルのCSVファイルでは1行目が見出し行となっている。そのため、csv.DictReader呼び出しにはファイルオブジェクトだけを渡している。このときには、1行目がフィールド名として解釈される。最初の要素の出力を見ると、「{'年': '1920年', '地域コード': '00000', '地域': '全国', '総人口': '55963053'}」のように辞書になっていることが確認できる。
CSVファイルに見出し行がないときには、以下のように、fieldnames引数に見出しを渡す。
filename = 'noheader.csv'
with open(filename, encoding='utf8', newline='') as f:
fieldnames = ['年','地域コード','地域','総人口']
csvreader = csv.DictReader(f, fieldnames=fieldnames)
for row in csvreader:
print(row)
Copyright© Digital Advantage Corp. All Rights Reserved.