【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を扱う:DictReaderDictWriter

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や他のデータベースとの連携、簡単なログファイルの解析、プログラム間でのデータ交換など、様々な場面で活躍します。特にDictReaderDictWriterを使うと、列名をキーとしてデータにアクセスできるため、コードが直感的になり、保守性も向上します。

これまでの標準ライブラリ(json, os, datetime, random)と組み合わせることで、さらに複雑で実用的な処理も実現できるようになります。ぜひ、色々なCSVファイルを扱ってみて、その便利さを実感してください!

次回もPythonの便利な標準ライブラリの世界を一緒に探検していきましょう!お楽しみに!

【Python標準ライブラリ入門 第6回】ファイル操作を極める!globで賢く検索、shutilで楽々コピー&移動・削除

その他の投稿はこちら

コメント

このブログの人気の投稿

タイトルまとめ

これで迷わない!WindowsでPython環境構築する一番やさしい方法 #0

【Python標準ライブラリ完結!】11の冒険をありがとう!君のPython力が飛躍する「次の一歩」とは? 🚀