Python で JSONL を扱う:読み取り・書き込み・解析

Python で JSONL(JSON Lines)ファイルを扱うための完全ガイド。組み込みモジュール、pandas、高性能ライブラリを使用して JSONL データの読み取り、書き込み、解析、ストリーミングを学びます。

最終更新:2026年2月

なぜ Python で JSONL を扱うのか?

Python は JSONL ファイルを扱うための最も人気のある言語です。組み込みの json モジュールが JSON 解析をすぐにサポートし、ファイルのイテレーションはデフォルトでメモリ効率が良く、pandas や orjson などの強力なライブラリが専門的なワークフロー向けに提供されています。機械学習データセット、アプリケーションログ、API レスポンスのいずれを処理する場合でも、Python は JSONL の処理を簡単にします。

JSONL(JSON Lines)は1行に1つの JSON オブジェクトを格納するため、ストリーミング、追記専用ロギング、すべてをメモリに読み込まずに大規模データセットを処理するのに最適です。Python の行ごとのファイル読み取りはこの形式と完璧に適合します。このガイドでは、JSONL を読み取る3つのアプローチ、書き込む2つのアプローチ、そしてメモリに収まりきらないファイルの処理方法を学びます。

Python で JSONL ファイルを読み取る

Python で JSONL ファイルを読み取る方法はいくつかあり、それぞれ異なる用途に適しています。標準の json モジュールはほとんどのシナリオで機能し、pandas は表形式の分析に便利で、ジェネレーターは大容量ファイルに最適です。

最も簡単なアプローチは Python 組み込みの json モジュールを使用します。ファイルを開き、行ごとにイテレートし、各行を json.loads() で解析します。すべてのレコードがメモリ上のリストに読み込まれます。

json モジュールによる基本的な読み取り
import json
records = []
with open('data.jsonl', 'r', encoding='utf-8') as f:
for line in f:
line = line.strip()
if line: # Skip empty lines
records.append(json.loads(line))
print(f'Loaded {len(records)} records')
print(records[0])

JSONL データが表形式(すべてのレコードに同じキーがある)の場合、pandas は1つの関数呼び出しで直接 DataFrame に読み込むことができます。構造化された JSONL データの分析を始める最速の方法です。

pandas による読み取り
import pandas as pd
# Read entire file into a DataFrame
df = pd.read_json('data.jsonl', lines=True)
print(df.head())
print(f'Shape: {df.shape}')
# For large files, read in chunks
chunks = pd.read_json('large.jsonl', lines=True, chunksize=10000)
for chunk in chunks:
# Process each chunk (DataFrame)
print(f'Chunk shape: {chunk.shape}')

メモリに収まらないほど大きなファイルには、ジェネレーター関数を使用します。一度に1レコードずつ返すため、ファイルサイズに関係なくメモリ使用量が一定に保たれます。本番のデータパイプラインで推奨されるパターンです。

大容量ファイル向けジェネレーターパターン
import json
from typing import Iterator, Any
def read_jsonl(path: str) -> Iterator[dict[str, Any]]:
"""Read a JSONL file lazily, yielding one record at a time."""
with open(path, 'r', encoding='utf-8') as f:
for line_num, line in enumerate(f, 1):
line = line.strip()
if not line:
continue
try:
yield json.loads(line)
except json.JSONDecodeError as e:
print(f'Skipping invalid JSON at line {line_num}: {e}')
# Process records one at a time
for record in read_jsonl('large_data.jsonl'):
process(record) # Only one record in memory at a time

Python で JSONL ファイルを書き込む

JSONL ファイルの書き込みは簡単です。各レコードを JSON 文字列にシリアライズし、改行文字を追加します。重要なルールは1行に1つの JSON オブジェクト、末尾のカンマやラッピング配列は不要です。

json.dumps() を使用して各レコードをシリアライズし、改行に続けて書き込みます。ensure_ascii=False を設定すると、出力内の中国語、日本語、絵文字などの Unicode 文字が保持されます。

json モジュールによる基本的な書き込み
import json
records = [
{"id": 1, "name": "Alice", "age": 30},
{"id": 2, "name": "Bob", "age": 25},
{"id": 3, "name": "Charlie", "age": 35},
]
with open('output.jsonl', 'w', encoding='utf-8') as f:
for record in records:
f.write(json.dumps(record, ensure_ascii=False) + '\n')
print(f'Wrote {len(records)} records to output.jsonl')

データがすでに pandas DataFrame にある場合、to_json() を orient='records' と lines=True で使用して、JSONL として直接エクスポートできます。これは pd.read_json() の lines=True の逆操作です。

pandas による書き込み
import pandas as pd
df = pd.DataFrame([
{"id": 1, "name": "Alice", "age": 30},
{"id": 2, "name": "Bob", "age": 25},
{"id": 3, "name": "Charlie", "age": 35},
])
# Write DataFrame to JSONL
df.to_json('output.jsonl', orient='records', lines=True, force_ascii=False)
print(f'Wrote {len(df)} records to output.jsonl')

JSONL 向け Python ライブラリ

Python には、異なるパフォーマンス特性を持つ複数の JSON 解析ライブラリがあります。適切なものを選ぶには、ファイルサイズとパフォーマンス要件に応じて判断します。

json(標準ライブラリ)

組み込み

Python 組み込みの json モジュールはインストール不要でどこでも動作します。ほとんどの JSONL ワークロードに十分で、すべての標準 JSON 型をサポートします。数百 MB までのファイルであれば十分なパフォーマンスです。

orjson

最速

orjson は Rust で書かれた最速の Python JSON ライブラリです。標準の json モジュールと比較して2〜10倍高速な解析とシリアライズを提供します。文字列ではなくバイトを出力し、dataclass、datetime、numpy、UUID 型をネイティブにサポートします。

ujson

高速

ujson(UltraJSON)は C ベースの JSON ライブラリで、標準の json モジュールより2〜5倍高速です。API は組み込みの json モジュールとほぼ同一のため、ドロップイン置換として使用できます。互換性と速度のバランスが良い選択肢です。

大容量 JSONL ファイルのストリーミング

ギガバイト規模の JSONL ファイルを処理する場合、データをバッチで読み取り、変換、書き込みするストリーミングアプローチが必要です。メモリ使用量を一定に保ち、進捗追跡も可能です。

大容量 JSONL ファイルのストリーミング
import json
import sys
def process_large_jsonl(
input_path: str,
output_path: str,
batch_size: int = 1000
) -> int:
"""Stream-process a large JSONL file in batches."""
processed = 0
batch: list[dict] = []
with open(input_path, 'r') as fin, \
open(output_path, 'w') as fout:
for line in fin:
line = line.strip()
if not line:
continue
record = json.loads(line)
# Transform the record
record['processed'] = True
batch.append(record)
if len(batch) >= batch_size:
for r in batch:
fout.write(json.dumps(r) + '\n')
processed += len(batch)
batch.clear()
print(f'\rProcessed {processed} records...', end='')
# Write remaining records
for r in batch:
fout.write(json.dumps(r) + '\n')
processed += len(batch)
print(f'\nDone. Processed {processed} records total.')
return processed
# Usage
process_large_jsonl('input.jsonl', 'output.jsonl', batch_size=5000)

このパターンは固定サイズのバッチでレコードを処理することで、メモリ使用量を一定に保ちます。batch_size パラメータでメモリ使用量と I/O 効率のトレードオフを制御します。ほとんどのシステムでは、1,000〜10,000 レコードのバッチが適切です。進捗インジケーターは長時間実行ジョブの監視に役立ちます。

無料 JSONL ツールを試す

コードを書きたくないですか?無料のオンラインツールを使って、JSONL ファイルの表示、検証、変換をブラウザで直接行えます。

JSONL ファイルをオンラインで操作

最大 1GB の JSONL ファイルをブラウザで表示、検証、変換。アップロード不要、100% プライベート。

よくある質問

Python で JSONL — 読み取り・書き込み・ストリーミング&バリデーション | jsonl.co