【Python標準ライブラリ入門 第5回】表データ処理の相棒!csvモジュールでCSVファイルを自在に操ろう 📊
「Excelで作った顧客リストをPythonで読み込んで処理したい…」
「プログラムで集計した結果を、他の人が使いやすいようにCSVファイルで出力したいな。」
「カンマ区切りのテキストデータって、どうやって扱えばいいの?」
こんにちは! Python標準ライブラリ探検隊へようこそ! 前回はos
モジュールを使ってファイルシステムと対話する方法を学び、プログラムがコンピュータの環境とより深く関われるようになりましたね。
シリーズ第5回の今回は、実務でも非常によく使われるデータ形式であるCSV (Comma Separated Values) ファイルをPythonで簡単に扱うための標準ライブラリ、csv
モジュールを徹底解説します! CSVファイルは、その名の通りデータをカンマで区切って並べたテキストファイルで、多くの表計算ソフトやデータベースシステムとのデータ交換に利用されています。csv
モジュールを使えば、これらのファイルをPythonで手軽に読み込んだり、PythonのデータをCSV形式で書き出したりすることができます。データ処理の第一歩として、csv
モジュールをマスターしましょう!(その他の投稿はこちら)
1. CSVファイルとは? なぜcsv
モジュールが便利?
CSV (Comma Separated Values) ファイルは、各行が1つのデータレコードを表し、行内の各フィールド(値)がカンマ (,
) で区切られている非常にシンプルなテキストファイル形式です。1行目をヘッダー行として、各列のフィールド名(列名)を記述することも一般的です。
例:
名前,年齢,都市
山田太郎,30,東京
佐藤花子,25,大阪
鈴木一郎,35,名古屋
なぜcsv
モジュールが便利なのでしょうか?
- 手軽なデータ交換: 多くのアプリケーション(Excel、Googleスプレッドシート、データベースなど)がCSV形式のインポート・エクスポートに対応しているため、異なるシステム間でのデータ交換が容易です。
- シンプルな構造: テキストベースなので、人間が直接見て内容を確認したり、簡単な編集を行ったりすることも可能です。
- Pythonでの扱いやすさ:
csv
モジュールを使うことで、CSVファイルの行や列の区切りを意識することなく、Pythonのリストや辞書といったデータ構造とスムーズに連携できます。例えば、カンマ区切りだけでなくタブ区切り(TSV)のファイルを扱ったり、値が引用符で囲まれている場合なども適切に処理してくれます。
json
モジュールが階層構造を持つデータに適しているのに対し、csv
モジュールは主に2次元の表形式データを扱うのに適しています。
2. csv
モジュールの基本的な使い方
まずは、csv
モジュールをインポートし、基本的な読み書きの方法を見ていきましょう。
2.1. モジュールのインポート
csv
モジュールを利用するには、まずインポートします。
import csv
2.2. CSVファイルの読み込み (csv.reader()
)
CSVファイルの内容を読み込むには、まずファイルを読み込みモード ('r'
) で開き、そのファイルオブジェクトをcsv.reader()
関数に渡します。csv.reader()
は、CSVファイルの各行をリストとして返すイテレータ(繰り返し可能なオブジェクト)を生成します。
サンプルCSVファイル (data.csv
として保存):
商品ID,商品名,価格
101,リンゴ,150
102,バナナ,100
103,ミカン,120
サンプルコード (Python):
import csv
file_path = 'data.csv'
try:
with open(file_path, mode='r', encoding='utf-8', newline='') as csvfile:
# newline='' は、CSVファイル内の改行コードの差異を吸収するためのおまじない
csv_reader = csv.reader(csvfile)
# ヘッダー行をスキップする場合 (もしあれば)
# header = next(csv_reader)
# print(f"ヘッダー: {header}")
print(f"\n--- '{file_path}' の内容 (行ごとのリスト) ---")
for row in csv_reader:
# row は各行のデータを要素とするリスト
# 例: ['101', 'リンゴ', '150']
print(row)
# 個々の要素にアクセス
if csv_reader.line_num == 1: # 1行目(ヘッダー)の処理を分ける例
print(f"列名: {row[0]}, {row[1]}, {row[2]}")
else:
product_id = row[0]
product_name = row[1]
price = int(row[2]) # 文字列なので必要に応じて型変換
print(f" 商品ID: {product_id}, 商品名: {product_name}, 価格: {price}円")
except FileNotFoundError:
print(f"エラー: ファイル '{file_path}' が見つかりません。")
except Exception as e:
print(f"エラーが発生しました: {e}")
newline=''
オプションは、異なるOS間での改行コードの扱いの違いによる問題を避けるためにopen()
関数で指定することが推奨されています。
2.3. CSVファイルへの書き込み (csv.writer()
)
Pythonのリストのリスト(各内部リストが1行のデータに相当)をCSVファイルに書き出すには、まずファイルを書き込みモード ('w'
) で開き、そのファイルオブジェクトをcsv.writer()
関数に渡します。そして、writerow()
メソッドで1行ずつ、またはwriterows()
メソッドで複数行を一度に書き込みます。
サンプルコード (Python):
import csv
output_file_path = 'output_data.csv'
# 書き込むデータ (リストのリスト)
header = ['名前', 'メールアドレス', '登録日']
data_to_write = [
['田中優', 'tanaka@example.com', '2025-01-15'],
['伊藤博', 'ito@example.jp', '2025-02-20'],
['渡辺恵子', 'watanabe@example.co.jp', '2025-03-10']
]
try:
with open(output_file_path, mode='w', encoding='utf-8', newline='') as csvfile:
csv_writer = csv.writer(csvfile)
# ヘッダー行を書き込む
csv_writer.writerow(header)
# データ行を複数まとめて書き込む
csv_writer.writerows(data_to_write)
# 1行ずつ書き込む場合はこうする
# for row_data in data_to_write:
# csv_writer.writerow(row_data)
print(f"\nデータが '{output_file_path}' に書き込まれました。")
except Exception as e:
print(f"エラーが発生しました: {e}")
# output_data.csv の中身 (例):
# 名前,メールアドレス,登録日
# 田中優,tanaka@example.com,2025-01-15
# 伊藤博,ito@example.jp,2025-02-20
# 渡辺恵子,watanabe@example.co.jp,2025-03-10
書き込み時もnewline=''
を指定するのが一般的です。
3. 辞書形式でCSVを扱う:DictReader
と DictWriter
CSVファイルの1行目をヘッダー(列名)として扱い、各行を辞書(キーが列名、値がその行のデータ)として読み書きできると非常に便利です。csv
モジュールは、そのためのDictReader
クラスとDictWriter
クラスを提供しています。
3.1. CSVファイルを辞書として読み込む (csv.DictReader()
)
csv.DictReader()
は、CSVファイルの各行を、ヘッダー行の値をキーとする辞書として返します。
サンプルコード (data.csv
を使用):
import csv
file_path = 'data.csv' # 商品ID,商品名,価格 のCSV
try:
with open(file_path, mode='r', encoding='utf-8', newline='') as csvfile:
dict_reader = csv.DictReader(csvfile) # 1行目が自動的にキーとして使われる
print(f"\n--- '{file_path}' の内容 (行ごとの辞書) ---")
for row_dict in dict_reader:
# row_dict は各行のデータを要素とする辞書
# 例: {'商品ID': '101', '商品名': 'リンゴ', '価格': '150'}
print(row_dict)
product_name = row_dict['商品名']
price = int(row_dict['価格'])
print(f" 商品名: {product_name}, 価格: {price}円")
except FileNotFoundError:
print(f"エラー: ファイル '{file_path}' が見つかりません。")
except Exception as e:
print(f"エラーが発生しました: {e}")
列名でデータにアクセスできるので、コードがより読みやすく、列の順番が変わっても影響を受けにくくなります。
3.2. 辞書のリストをCSVファイルに書き込む (csv.DictWriter()
)
csv.DictWriter()
を使うと、Pythonの辞書のリストをCSVファイルに書き出すことができます。この際、書き出す列の順番(フィールド名)を指定する必要があります。
サンプルコード:
import csv
output_dict_file_path = 'output_dict_data.csv'
# 書き込むデータ (辞書のリスト)
data_to_write_dict = [
{'名前': '山本譲二', '年齢': 42, '部署': '営業', '役職': '課長'},
{'名前': '中村咲子', '年齢': 29, '部署': '開発', '役職': 'エンジニア'},
{'名前': '小林健太', '年齢': 33, '部署': '人事', '役職': '主任'}
]
# CSVファイルのヘッダー行(フィールド名)を指定
field_names = ['名前', '部署', '役職', '年齢'] # 書き出す順番もこれで決まる
try:
with open(output_dict_file_path, mode='w', encoding='utf-8', newline='') as csvfile:
dict_writer = csv.DictWriter(csvfile, fieldnames=field_names)
dict_writer.writeheader() # ヘッダー行を書き込む
dict_writer.writerows(data_to_write_dict) # 複数行の辞書データを書き込む
# 1行ずつ書き込む場合はこうする
# for row_dict_data in data_to_write_dict:
# dict_writer.writerow(row_dict_data)
print(f"\nデータが '{output_dict_file_path}' に書き込まれました。")
except Exception as e:
print(f"エラーが発生しました: {e}")
# output_dict_data.csv の中身 (例):
# 名前,部署,役職,年齢
# 山本譲二,営業,課長,42
# 中村咲子,開発,エンジニア,29
# 小林健太,人事,主任,33
fieldnames
で指定した順番で列が書き出されます。辞書に含まれないキーは無視され、fieldnames
にあって辞書にないキーは空の値として書き出されます(オプションで制御可能)。
4. 少し高度なオプション:区切り文字や引用符の指定
CSVファイルはカンマ区切りが基本ですが、時にはタブ区切り(TSVファイル)やセミコロン区切りのファイルも存在します。また、値自体にカンマや改行が含まれる場合、その値はダブルクォート("
)などで囲まれることがあります。csv
モジュールでは、これらの挙動をオプションで制御できます。
delimiter
引数: 区切り文字を指定します (例:delimiter='\t'
でタブ区切り)。quotechar
引数: 値を囲む引用符を指定します (例:quotechar='"'
)。quoting
引数: 引用符で囲むルールを指定します (例:csv.QUOTE_ALL
ですべてのフィールドを囲む、csv.QUOTE_MINIMAL
で必要な場合のみ囲む(デフォルト)、csv.QUOTE_NONNUMERIC
で数値以外のフィールドを囲むなど)。
import csv
import io # 文字列をファイルのように扱うためのモジュール
# タブ区切り、全ての値をダブルクォートで囲むCSVデータ例 (文字列として)
tsv_data_string = '"名前"\t"年齢"\t"都市"\n"Alice"\t"25"\t"New York"\n"Bob"\t"30"\t"London"'
# 文字列をファイルのように読み込む
# io.StringIOを使うと、文字列をファイルオブジェクトのように扱える
file_like_object = io.StringIO(tsv_data_string)
# readerでオプションを指定
csv_reader_custom = csv.reader(file_like_object, delimiter='\t', quotechar='"')
print("\n--- カスタム区切り文字・引用符のCSV読み込み ---")
for row in csv_reader_custom:
print(row)
# writerでオプションを指定する例
data_to_write_custom = [['Name with, comma', 100], ['Another "Name"', 200]]
output_string_io = io.StringIO() # 書き出し先を文字列バッファに
csv_writer_custom = csv.writer(output_string_io, delimiter=';', quotechar="'", quoting=csv.QUOTE_ALL)
csv_writer_custom.writerows(data_to_write_custom)
print("\n--- カスタム区切り文字・引用符でのCSV書き出し (文字列として表示) ---")
print(output_string_io.getvalue())
output_string_io.close()
様々な形式のCSVファイルに対応できる柔軟性がcsv
モジュールの魅力の一つです。
まとめ:csv
モジュールで表データ処理をシンプルに!
今回は、Pythonの標準ライブラリ解説シリーズ第5回として、csv
モジュールの基本的な使い方を学びました。
- CSVファイルの読み込み (
csv.reader()
) と書き込み (csv.writer()
) - ヘッダー行を意識した辞書形式での読み書き (
csv.DictReader()
,csv.DictWriter()
) - ファイルを開く際の
newline=''
や文字エンコーディング指定の重要性 - 区切り文字や引用符を指定するオプション
csv
モジュールは、表形式のデータを扱う際の基本となる強力なツールです。Excelや他のデータベースとの連携、簡単なログファイルの解析、プログラム間でのデータ交換など、様々な場面で活躍します。特にDictReader
やDictWriter
を使うと、列名をキーとしてデータにアクセスできるため、コードが直感的になり、保守性も向上します。
これまでの標準ライブラリ(json
, os
, datetime
, random
)と組み合わせることで、さらに複雑で実用的な処理も実現できるようになります。ぜひ、色々なCSVファイルを扱ってみて、その便利さを実感してください!
次回もPythonの便利な標準ライブラリの世界を一緒に探検していきましょう!お楽しみに!
【Python標準ライブラリ入門 第6回】ファイル操作を極める!globで賢く検索、shutilで楽々コピー&移動・削除
コメント
コメントを投稿