記事一覧へ戻る 本の順番で続きを読む

データ処理 - CSV・JSON・SQLiteの実践

Python3中級 | 2026/02/18 15:44

データ処理

CSVの実践的な操作

import csv
from pathlib import Path

# DictWriterで辞書からCSVを作成
users = [
    {'name': '太郎', 'age': 25, 'score': 85},
    {'name': '花子', 'age': 30, 'score': 92},
    {'name': '次郎', 'age': 22, 'score': 78},
]

with open('users.csv', 'w', encoding='utf-8', newline='') as f:
    writer = csv.DictWriter(f, fieldnames=['name', 'age', 'score'])
    writer.writeheader()
    writer.writerows(users)

# 集計処理
with open('users.csv', 'r', encoding='utf-8') as f:
    reader = csv.DictReader(f)
    scores = [int(row['score']) for row in reader]
    print(f"平均点: {sum(scores) / len(scores):.1f}")
    print(f"最高点: {max(scores)}")

JSONの実践的な操作

import json
from datetime import datetime

# カスタムエンコーダ
class DateTimeEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, datetime):
            return obj.isoformat()
        return super().default(obj)

data = {
    'event': '会議',
    'date': datetime(2026, 3, 15, 14, 0),
    'attendees': ['太郎', '花子']
}

# シリアライズ
json_str = json.dumps(data, cls=DateTimeEncoder, ensure_ascii=False, indent=2)
print(json_str)

# APIレスポンスの処理
import urllib.request

def fetch_json(url):
    with urllib.request.urlopen(url) as response:
        return json.loads(response.read().decode())

SQLite

import sqlite3

# データベース接続(ファイルがなければ作成)
conn = sqlite3.connect('app.db')
conn.row_factory = sqlite3.Row  # 辞書風アクセス
cursor = conn.cursor()

# テーブル作成
cursor.execute('''
    CREATE TABLE IF NOT EXISTS users (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        name TEXT NOT NULL,
        email TEXT UNIQUE,
        age INTEGER,
        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    )
''')

# データ挿入(パラメータ化クエリでSQLインジェクション防止)
cursor.execute(
    'INSERT INTO users (name, email, age) VALUES (?, ?, ?)',
    ('太郎', 'taro@example.com', 25)
)

# 複数行挿入
users = [
    ('花子', 'hanako@example.com', 30),
    ('次郎', 'jiro@example.com', 22),
]
cursor.executemany(
    'INSERT INTO users (name, email, age) VALUES (?, ?, ?)',
    users
)
conn.commit()

# 検索
cursor.execute('SELECT * FROM users WHERE age >= ?', (25,))
for row in cursor.fetchall():
    print(f"{row['name']} ({row['age']}歳): {row['email']}")

# コンテキストマネージャの使用
with sqlite3.connect('app.db') as conn:
    conn.row_factory = sqlite3.Row
    rows = conn.execute('SELECT * FROM users').fetchall()

conn.close()

データ処理パイプライン

def load_csv(path):
    with open(path, 'r', encoding='utf-8') as f:
        return list(csv.DictReader(f))

def transform(records):
    for r in records:
        r['age'] = int(r['age'])
        r['score'] = int(r['score'])
        r['grade'] = 'A' if r['score'] >= 90 else 'B' if r['score'] >= 80 else 'C'
    return records

def save_json(records, path):
    with open(path, 'w', encoding='utf-8') as f:
        json.dump(records, f, ensure_ascii=False, indent=2)

# パイプライン実行
data = load_csv('users.csv')
data = transform(data)
save_json(data, 'users_graded.json')

まとめ

  • csv.DictReader/DictWriter で辞書形式のCSV操作
  • json.JSONEncoder をカスタマイズしてdatetime等を変換
  • sqlite3 でローカルデータベースを手軽に使える
  • パラメータ化クエリ ? でSQLインジェクションを防止
  • データ処理はETLパイプライン(抽出→変換→保存)で整理