HOWTO · Python

Python でヘッダー付きの CSV を読む

Python でヘッダー付きの CSV を読み取る方法を学びます。

このページの内容

Python の標準ライブラリである csv モジュールを使うと、カンマ区切りファイルを行ごとに読み取れます。CSV ファイルでは、先頭行に列名があり、その後にレコードが続く形式がよく使われます。ここでの例はその形式を前提としていますが、csv.reader 自体が先頭行をヘッダーとして自動的に扱うわけではありません。返されるのは行の反復可能オブジェクトで、各行は文字列のリストです。

各例では小さな入力ファイルを自分で作成するため、別のファイルをダウンロードせずに試せます。実際のファイルを使う場合は、一時ファイルを作成する部分をそのファイルのパスに置き換え、newline="" と、そのファイルに適したエンコーディングを指定して開いてください。入力例として、サンプルの メール用 CSV ファイル も確認できます。各例の後には、実行時に得られた結果が表示されます。

Python でヘッダー付きの CSV ファイルを読む

開いたテキストファイルを csv.reader に渡し、返された結果を反復処理します。ループにはすべての行が含まれるため、最初に表示されるリストは列名の行です。ヘッダーを別に扱う前に、元のレコードを確認したい場合に便利です。

次の例を実行します。

このセクションのコードと表示されるラベルや出力は英語のままです。

import csv
import tempfile

with tempfile.NamedTemporaryFile(mode="w", encoding="utf-8", newline="", delete=False) as source:
    source.write("name,team\nAda,Research\nLin,Design\n")
    path = source.name

with open(path, encoding="utf-8", newline="") as source:
    rows = csv.reader(source)
    for row in rows:
        print(row)
['name', 'team']
['Ada', 'Research']
['Lin', 'Design']

リーダーは CSV の引用符の規則に従ってフィールドを解析します。各行をカンマで単純に分割すると、引用符で囲まれたフィールド内にカンマがある場合、正しく処理できないことがあります。ファイルを反復処理すると一度の走査で読み取るため、処理時間は入力サイズに対して線形に増加します。ファイルが大きくても、この方法ではすべての行を一度にメモリへ保持する必要はありません。

ヘッダーを取り出して行を分けて処理する

リーダーに組み込み関数 next() を適用すると、先頭行を読み取ってヘッダーとして保存できます。リーダーは次の行から読み取りを続けるため、ループではデータレコードだけを処理できます。ファイル全体をリストに読み込まずに、列名と値を分けて扱えます。

次の例を実行します。

このセクションのコードと表示されるラベルや出力は英語のままです。

import csv
import tempfile

with tempfile.NamedTemporaryFile(mode="w", encoding="utf-8", newline="", delete=False) as source:
    source.write("name,team\nAda,Research\nLin,Design\n")
    path = source.name

with open(path, encoding="utf-8", newline="") as source:
    rows = csv.reader(source)
    header = next(rows)
    print("Header:", ", ".join(header))
    for row in rows:
        print(dict(zip(header, row)))
Header: name, team
{'name': 'Ada', 'team': 'Research'}
{'name': 'Lin', 'team': 'Design'}

ここでは zip が各列名と対応するフィールドを組み合わせ、dict によってその組み合わせを名前で参照できるようにしています。この方法は、ファイルにヘッダー行があり、各レコードのフィールドが同じ順序で並んでいることを前提とします。行がない可能性のあるファイルでは、ヘッダーとして使う前に先頭行があるか確認してください。行がなければ next() が返す行はありません。例の中の「Header:」という表示ラベルは、変更できない出力の一部であるため英語のままです。

異なる delimiter を指定して CSV を読む

既定の区切り文字はカンマです。セミコロンを使うファイルでは、delimiter 引数を csv.reader に渡します。入力で実際にフィールドを区切っている文字を指定してください。リーダーの動作は同じですが、ヘッダーの扱いは明示的に行います。慣例として先頭行にヘッダーが含まれますが、csv.reader がそれをヘッダーとして解釈するわけではありません。そのため、この例ではレコードを表示する前に next() で先頭行を読み取ります。

次の例を実行します。

このセクションのコードと表示されるラベルや出力は英語のままです。

import csv
import tempfile

with tempfile.NamedTemporaryFile(mode="w", encoding="utf-8", newline="", delete=False) as source:
    source.write("name;team\nAda;Research\nLin;Design\n")
    path = source.name

with open(path, encoding="utf-8", newline="") as source:
    rows = csv.reader(source, delimiter=";")
    header = next(rows)
    print("Header:", ", ".join(header))
    for row in rows:
        print(", ".join(row))
Header: name, team
Ada, Research
Lin, Design

別の形式では、タブ文字など、そのファイルで使われている区切り文字を delimiter に指定します。CSV モジュール用にファイルを開くときは newline="" を指定し、元データに合ったエンコーディングを選んでください。引用符で囲まれたフィールドや改行を含むフィールドがある場合は、自分で行を前処理せず、csv.reader に解析させます。例の中の「Header:」という表示ラベルは、変更できない出力の一部であるため英語のままです。