1日目のゴール
1日目のテーマは
「csvモジュールを使って、CSVファイルを“怖くない実務データ”として扱える感覚をつかむこと」 です。
今日つかみたいのは、この2つです。
CSVってそもそも何者か(ただのテキストファイルだという感覚)csv モジュールで「読む」「書く」の最小パターン
ここが見えれば、明日以降の「集計」「フィルタ」「変換」が一気に楽になります。
CSVファイルって何?をちゃんとイメージする
Excelファイルとの違いをざっくり理解する
まず、「CSVって何?」を言葉でつかみます。
CSV は
Comma Separated Values
=「カンマで区切られた値たち」
という意味の、ただのテキストファイルです。
例えば、こんな内容のファイルがあったとします。
id,name,age
1,Taro,25
2,Hanako,30
3,Ken,22
1行目は「列の名前」
2行目以降は「1人分のデータ」
カンマで区切られているだけのテキストです。
Excel で開くと表っぽく見えますが、
中身はあくまで「文字列の行が並んでいるだけ」です。
ここをちゃんと理解しておくと、
「Python で扱うのが怖くなくなる」んですよね。
csvモジュールを使う理由
自分で split してもいいけど…?
実は、CSVはテキストなので、
極論を言えばこうやっても読めます。
line = "1,Taro,25"
parts = line.split(",")
# ["1", "Taro", "25"]
Pythonでも、現実のCSVはもっとややこしいです。
名前にカンマが入っている
「”」で囲まれている
改行を含むセルがある
こういうケースを自前で全部処理するのは、かなりしんどいです。
そこで登場するのが csv モジュールです。
csv は、
「CSVの面倒なルールを全部知っていて、いい感じに読み書きしてくれるやつ」
だと思ってください。
まずは読み込みの最小パターンを覚える
csv.reader で「行ごとのリスト」として読む
一番シンプルな読み方からいきます。
事前に、こんな people.csv があるとします。
id,name,age
1,Taro,25
2,Hanako,30
3,Ken,22
これを Python で読み込んで、
1行ずつ表示してみましょう。
import csv
def read_csv_basic():
with open("people.csv", "r", encoding="utf-8", newline="") as f:
reader = csv.reader(f)
for row in reader:
print(row)
read_csv_basic()
Python実行すると、こんな感じで出ます。
['id', 'name', 'age']
['1', 'Taro', '25']
['2', 'Hanako', '30']
['3', 'Ken', '22']
ここで深掘りしたいポイントがいくつかあります。
csv.reader(f) は、「ファイル f をCSVとして読むためのオブジェクト」を返す。for row in reader: で「1行ずつ、リストとして取り出している」。
各 row は「文字列のリスト」であり、数字も一旦は文字列として入っている。
つまり、
「CSVの1行=Pythonでは“文字列のリスト”として扱う」
という感覚を持てればOKです。
ヘッダー行をスキップして読む
1行目は「列名」として扱いたい
実務では、1行目は「ヘッダー(列名)」であることが多いです。
さっきの people.csv もそうでした。
id,name,age ← ヘッダー
1,Taro,25
2,Hanako,30
3,Ken,22
「データとして扱うのは2行目以降だけにしたい」
という場合、こう書けます。
import csv
def read_csv_skip_header():
with open("people.csv", "r", encoding="utf-8", newline="") as f:
reader = csv.reader(f)
header = next(reader) # 1行目を読み飛ばす
print("ヘッダー:", header)
for row in reader:
print("データ行:", row)
read_csv_skip_header()
Pythonここでの重要ポイントは、
next(reader) で「最初の1行だけ先に読む」こと。
その後の for row in reader: では、2行目以降が順番に出てくること。
この「ヘッダーを next で1回読む」というパターンは、
CSVを扱うときの定番テクニックです。
行のリストを「意味のある変数」に割り当てる
インデックスのままだと読みにくい
さっきの row は、こんなリストでした。
row = ['1', 'Taro', '25']
Pythonこれをそのまま row[0], row[1], row[2] と使うと、
「どれが何の列か」が分かりにくくなります。
そこで、こうします。
import csv
def read_csv_with_unpack():
with open("people.csv", "r", encoding="utf-8", newline="") as f:
reader = csv.reader(f)
next(reader) # ヘッダーを読み飛ばす
for row in reader:
person_id, name, age_text = row
age = int(age_text)
print(f"ID={person_id}, 名前={name}, 年齢={age}")
Pythonここで深掘りしたいのは、
person_id, name, age_text = row という「アンパック」の書き方。row[0] などを使わず、「意味のある名前の変数」に分解していること。
年齢は int() で整数に変換してから使っていること。
これで、コードの読みやすさが一気に上がります。
csv.writer でCSVファイルに書き込む
まずは「新規に書き出す」パターン
今度は逆方向、「書く」側です。
例えば、Python の中にこんなデータがあるとします。
people = [
["id", "name", "age"],
["1", "Taro", "25"],
["2", "Hanako", "30"],
["3", "Ken", "22"],
]
Pythonこれを output.csv に書き出してみます。
import csv
def write_csv_basic():
people = [
["id", "name", "age"],
["1", "Taro", "25"],
["2", "Hanako", "30"],
["3", "Ken", "22"],
]
with open("output.csv", "w", encoding="utf-8", newline="") as f:
writer = csv.writer(f)
for row in people:
writer.writerow(row)
print("output.csv に書き込みました。")
Pythonここでの重要ポイントは、
csv.writer(f) で「CSVとして書くためのオブジェクト」を作っていること。writer.writerow(row) に「リスト」を渡すと、そのまま1行分として書かれること。newline="" を open に渡しているのは、「余計な空行が入る問題」を防ぐための定番設定であること。
これで、output.csv の中身はこうなります。
id,name,age
1,Taro,25
2,Hanako,30
3,Ken,22
実務っぽいミニアプリ:CSVを読み込んで、別のCSVに変換する
「読み込み」と「書き込み」をつなげてみる
1日目の仕上げとして、
こんなミニアプリを考えてみましょう。
people.csv を読み込む
年齢が 25 歳以上の人だけを抽出する
その結果を people_over25.csv に書き出す
コードはこうなります。
import csv
def filter_people_over_25(input_file, output_file):
with open(input_file, "r", encoding="utf-8", newline="") as f_in:
reader = csv.reader(f_in)
header = next(reader)
filtered_rows = []
filtered_rows.append(header)
for row in reader:
person_id, name, age_text = row
age = int(age_text)
if age >= 25:
filtered_rows.append(row)
with open(output_file, "w", encoding="utf-8", newline="") as f_out:
writer = csv.writer(f_out)
for row in filtered_rows:
writer.writerow(row)
print(f"{output_file} に 25歳以上のデータを書き出しました。")
def main():
filter_people_over_25("people.csv", "people_over25.csv")
main()
Pythonこのコードを、日本語だけで分解してみます。
入力ファイルを開き、csv.reader で読む準備をする。
ヘッダーを1行読み飛ばしつつ、filtered_rows にまずヘッダーを入れておく。
2行目以降を1行ずつ読み、年齢を整数に変換する。
25歳以上なら、その行を filtered_rows に追加する。
読み終わったら、出力ファイルを開き、csv.writer で filtered_rows を1行ずつ書き出す。
これだけで、
「CSVを読み込んで条件でフィルタし、別のCSVとして出力する」
という、かなり実務寄りの処理ができています。
1日目で絶対に押さえておきたいポイント
「CSV+csvモジュール」の頭の中の地図
今日の本質を、ぎゅっとまとめるとこうです。
CSV は「カンマ区切りのテキスト」であり、1行=1レコード。csv.reader は「1行を“文字列のリスト”として返してくれる読み取り器」。csv.writer は「“文字列のリスト”を1行として書き出してくれる書き込み器」。
ヘッダー行は next(reader) で1回だけ先に読むのが定番。
行のリストは「意味のある変数」にアンパックしてから使うと読みやすい。
2日目以降は、
ここに「辞書形式で読む」「列名でアクセスする」「集計する」などを足していきます。
でも、土台は今日やったこの2つだけです。
「読む(reader)」
「書く(writer)」
この感覚さえつかめていれば、
CSVはもう“実務データ”として怖くありません。

