ファイル形式の処理:CSV、JSON、TXT
csvモジュール、json.load/dump、エージェントツール向けの安全なテキストエンコーディングを学びます。
「ファイル形式の処理:CSV、JSON、TXT」はCoddyKit上の無料AI Agentsレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはAI Agents学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 AI Agentsコースには全4レッスンが含まれています。
エージェントで最もよく使う3つのファイル形式
エージェントが常に読み書きするファイル形式は、表形式データ用のCSV、構造化オブジェクト用のJSON、ログやプロンプト、レポート用のプレーンテキストの3つです。それぞれ解析要件、エッジケース、ベストプラクティスが異なります。Pythonはこの3つすべてに優れた組み込みサポートを提供しています。
import csv
import json
from pathlib import Path
# Detect format from extension
def read_data_file(file_path):
path = Path(file_path)
if path.suffix == '.csv':
return read_csv(path)
elif path.suffix == '.json':
return read_json(path)
elif path.suffix == '.txt':
return path.read_text(encoding='utf-8')
else:
raise ValueError(f'Unsupported format: {path.suffix}')csv.reader — 基本的なCSV解析
csv.readerはCSVファイルを1行ずつ解析し、各行を文字列のリストとして返します。手作業でカンマ分割する方法とは異なり、引用符で囲まれたフィールド、値の中にあるカンマ、引用符で囲まれた値の中の改行を正しく処理します。
import csv
with open('sales.csv', 'w', newline='') as f:
f.write('product,qty,price\nWidget,3,9.99\nGadget,1,19.99\n')
with open('sales.csv', 'r', encoding='utf-8', newline='') as f:
reader = csv.reader(f)
header = next(reader)
print('Columns:', header)
for row in reader:
product = row[0]
quantity = int(row[1])
price = float(row[2])
print(f'{product}: {quantity} units at ${price}')csv.DictReader — 行を辞書として扱う
csv.DictReaderは各行を、列見出しをキーとするOrderedDict(Python 3.8以降では通常のdict)として読み込みます。位置によるインデックス指定よりも扱いやすく、列の順序が変わってもコードの読みやすさを保てます。
import csv
with open('employees.csv', 'w', newline='') as f:
f.write('name,department,salary\nAlice,Eng,95000\nBob,Sales,70000\n')
with open('employees.csv', 'r', encoding='utf-8', newline='') as f:
reader = csv.DictReader(f)
print('Fields:', reader.fieldnames)
total_salary = 0
for row in reader:
name = row['name']
department = row['department']
salary = float(row['salary'])
total_salary += salary
print(f'{name} ({department}): ${salary:,.2f}')
print(f'Total payroll: ${total_salary:,.2f}')csv.writerとDictWriter — CSVの書き込み
行をリストとして書き込むにはcsv.writerを、辞書として書き込むにはcsv.DictWriterを使用します。ファイルを開くときは、必ずnewline=''を渡してください。csvモジュール自体が行末を処理するため、Windowsで改行が二重になるのを防げます。
import csv
results = [
{'task_id': 'T001', 'status': 'completed', 'duration_s': 12.5},
{'task_id': 'T002', 'status': 'failed', 'duration_s': 3.1},
{'task_id': 'T003', 'status': 'completed', 'duration_s': 45.8},
]
fieldnames = ['task_id', 'status', 'duration_s']
with open('task_results.csv', 'w', newline='', encoding='utf-8') as f:
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader() # write column names
writer.writerows(results)
print('Wrote task_results.csv')json.load()とjson.dump() — ファイルI/O
JSONファイルの解析にはjson.load(file)を、書き込みにはjson.dump(obj, file)を使用します。これらはファイルオブジェクトを扱います。文字列にはjson.loads(string)とjson.dumps(obj)を使用してください。読みやすい出力にするため、常にindent=2を使用します。
import json
with open('config.json', 'w', encoding='utf-8') as f:
json.dump({'api_url': 'https://api.example.com', 'timeout': 15}, f)
with open('config.json', 'r', encoding='utf-8') as f:
config = json.load(f)
print('API URL:', config.get('api_url'))
print('Timeout:', config.get('timeout', 30))
output_data = {
'run_id': 'abc123',
'items': [1, 2, 3],
'meta': {'agent': 'v2', 'model': 'gpt-4o'}
}
with open('output.json', 'w', encoding='utf-8') as f:
json.dump(
output_data, f,
indent=2,
ensure_ascii=False
)
print('Written output.json')JSONデコードエラーへの対処
エージェントのパイプラインでは、不完全な書き込み、途中で切れたダウンロード、エンコーディングの問題などにより、壊れたJSONファイルがよく発生します。json.load()は必ずtry/exceptで囲み、デバッグに役立つようファイルパスを含む明確なエラーメッセージを提示してください。
import json
from pathlib import Path
def safe_load_json(file_path):
path = Path(file_path)
try:
with open(path, 'r', encoding='utf-8') as f:
return json.load(f)
except json.JSONDecodeError as e:
print(f'Invalid JSON in {path}: line {e.lineno}, col {e.colno}')
print(f' Error: {e.msg}')
# Show the problem area
content = path.read_text(encoding='utf-8')
lines = content.split('\n')
if e.lineno <= len(lines):
print(f' Content: {lines[e.lineno-1][:80]}')
return None
except FileNotFoundError:
print(f'File not found: {path}')
return None
# --- demo ---
Path('good.json').write_text('{"model": "gpt-4o"}', encoding='utf-8')
Path('bad.json').write_text('{"model": "gpt-4o", }', encoding='utf-8')
print('Loading good.json:', safe_load_json('good.json'))
print('Loading bad.json:', safe_load_json('bad.json'))
JSONL(JSON Lines)形式の読み込み
多くのAI APIやデータパイプラインでは、JSONL(JSON Lines)を使用します。これは1行に1つのJSONオブジェクトを置く形式です。ファイル全体をメモリに読み込まず、1行ずつ処理できるため、ストリーミングに対応しやすく、扱いも簡単です。各行が完全に独立したJSONオブジェクトになっています。
import json
with open('events.jsonl', 'w', encoding='utf-8') as f:
f.write('{"event": "start"}\n{"event": "stop"}\nnot json\n')
results = []
with open('events.jsonl', 'r', encoding='utf-8') as f:
for line_num, line in enumerate(f, 1):
line = line.strip()
if not line:
continue
try:
event = json.loads(line)
results.append(event)
except json.JSONDecodeError as e:
print(f'Bad JSON on line {line_num}: {e}')
print(f'Loaded {len(results)} events')
with open('output.jsonl', 'w', encoding='utf-8') as f:
for record in results:
f.write(json.dumps(record, ensure_ascii=False) + '\n')プレーンテキストファイルの読み込み
プレーンテキストは、ログ、プロンプト、レポート、設定ファイルなどに使われる最も単純な形式です。.read()でファイル全体を読み込むことも、1行ずつ処理することもできます。大きなファイルでは、メモリ使用量を一定に保つため、必ず1行ずつ処理してください。
from pathlib import Path
Path('system_prompt.txt').write_text('You are a helpful agent.', encoding='utf-8')
with open('agent.log', 'w', encoding='utf-8') as f:
f.write('INFO: boot\nERROR: disk full\nCRITICAL: crash\nINFO: recovered\n')
prompt = Path('system_prompt.txt').read_text(encoding='utf-8')
print(f'Prompt length: {len(prompt)} characters')
error_lines = []
with open('agent.log', 'r', encoding='utf-8') as f:
for line in f:
line = line.rstrip()
if not line:
continue
if 'ERROR' in line or 'CRITICAL' in line:
error_lines.append(line)
print(f'Found {len(error_lines)} error lines')
with open('summary.txt', 'w', encoding='utf-8') as f:
f.write('Agent Run Summary\n')
f.write('=' * 40 + '\n')
for error in error_lines[:10]:
f.write(f' {error}\n')
print('Summary written')BOM(バイトオーダーマーク)への対処
ExcelやWindowsのツールから出力したファイルは、先頭にBOM(バイトオーダーマーク)という不可視の\ufeff文字が含まれていることがよくあります。対処しないと、CSV解析時に最初のフィールド名が壊れてしまいます。encoding='utf-8-sig'を使用すると、自動的にBOMを取り除けます。
import csv
with open('windows_export.csv', 'wb') as f:
f.write('name,email,age\nAlice,alice@x.com,30\n'.encode('utf-8'))
with open('file.txt', 'wb') as f:
f.write(b'\xef\xbb\xbfhello')
with open('windows_export.csv', 'r', encoding='utf-8') as f:
reader = csv.DictReader(f)
first = next(reader)
print(list(first.keys()))
with open('windows_export.csv', 'r', encoding='utf-8-sig') as f:
reader = csv.DictReader(f)
first = next(reader)
print(list(first.keys()))
content = open('file.txt', 'rb').read()
if content.startswith(b'\xef\xbb\xbf'):
content = content[3:]
text = content.decode('utf-8')
print('Decoded:', text)エンコーディングエラーへの対処
不明なソースからファイルを読み込むときは、エンコーディングエラーがよく発生します。open()のerrorsパラメーターで処理方法を指定できます。'replace'は不正な文字を?に置き換え、'ignore'は不正な文字を削除し、'backslashreplace'はエスケープします。厳密に検証する場合は、デフォルトの'strict'を使用してください。
from pathlib import Path
def read_with_fallback(file_path):
path = Path(file_path)
# Try UTF-8 first
try:
return path.read_text(encoding='utf-8')
except UnicodeDecodeError:
pass
# Try Latin-1 (handles most European files)
try:
return path.read_text(encoding='latin-1')
except UnicodeDecodeError:
pass
# Last resort: replace bad characters
text = path.read_text(encoding='utf-8', errors='replace')
print(f'Warning: {path.name} had encoding errors (chars replaced)')
return text
# --- demo ---
Path('notes_utf8.txt').write_text('Notes: café, naïve, résumé', encoding='utf-8')
text = read_with_fallback('notes_utf8.txt')
print(f'Read {len(text)} chars: {text!r}')
壊れたCSVファイルへの対処
実際のCSVファイルには、余分なカンマ、欠落したフィールド、一貫しない引用符、区切り文字の混在などの問題があります。quotingとerror_bad_linesのオプションを使用し、行の解析をtry/exceptで囲んで、不正な行を適切にスキップしてください。
import csv
with open('messy_data.csv', 'w', newline='') as f:
f.write('name,email,score\nAlice,alice@x.com,88\nBob,,90\nCarol,carol@x.com,notanumber\n')
valid_rows = []
error_count = 0
with open('messy_data.csv', 'r', encoding='utf-8', newline='') as f:
reader = csv.DictReader(f)
expected_fields = {'name', 'email', 'score'}
for line_num, row in enumerate(reader, start=2):
try:
if not all(row.get(f, '').strip() for f in expected_fields):
raise ValueError(f'Missing required field in row {line_num}')
score = float(row['score'])
valid_rows.append({
'name': row['name'].strip(),
'email': row['email'].strip().lower(),
'score': score
})
except (ValueError, KeyError) as e:
error_count += 1
print(f'Skipping row {line_num}: {e}')
print(f'Valid: {len(valid_rows)}, Errors: {error_count}')クイックチェック:CSVのDictReaderとreaderの比較
CSVの解析オプションについての理解度を確認しましょう。
ファイル形式の扱いのまとめ
これで、エージェントで使われる主要なファイル形式をすべて解析および書き込みできるようになりました。
- CSV:辞書形式の行には
csv.DictReader、出力にはcsv.DictWriterを使用し、ファイルを開くときは必ずnewline=''を指定します - JSON:解析には
json.load(f)、書き込みにはjson.dump(obj, f, indent=2)を使用し、JSONDecodeErrorを捕捉します - JSONL:
json.loads(line)で各行を読み込んで解析します。ストリーミングデータに適しています - プレーンテキスト:小さなファイルには
.read()、大きなファイルには1行ずつの反復処理を使用します - BOM:Windowsから出力されたファイルには
encoding='utf-8-sig'を使用します - エンコーディングエラー:UTF-8を試し、必要に応じてlatin-1にフォールバックするか、
errors='replace'を使用します
よくある質問
「ファイル形式の処理:CSV、JSON、TXT」レッスンは無料ですか?
はい。「ファイル形式の処理:CSV、JSON、TXT」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、AI Agentsコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 AI Agentsコースには全4レッスンが含まれています。
「ファイル形式の処理:CSV、JSON、TXT」で何を学びますか?
csvモジュール、json.load/dump、エージェントツール向けの安全なテキストエンコーディングを学びます。 ブラウザで直接実行するハンズオンコードでAI Agentsを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
AI Agentsを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのAI Agentsは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。
「ファイル形式の処理:CSV、JSON、TXT」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このAI Agentsレッスンでコードを書いて実行できますか?
はい。すべてのAI Agentsレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- エージェントコンテキストでのファイルの読み書き
- ディレクトリトラバーサルとファイル探索
- ファイル形式の処理:CSV、JSON、TXT
- エラーハンドリングを伴う安全なファイル操作