pandas で JSON を読み書きする(read_json / to_json)

CSV と並んでよく使われるデータ形式に JSON があります。Web API のレスポンスや設定ファイルなどで広く使われており、pandas にも JSON を直接読み書きするための関数が用意されています。

read_json で JSON を読み込む

もっとも基本的な使い方は、JSON ファイルのパスを渡して DataFrame に変換する方法です。

import pandas as pd

df = pd.read_json("data.json")
print(df)

JSON の構造が「レコードの配列」になっていれば、各要素が 1 行として読み込まれます。たとえば次のような JSON ファイルを想定しています。

[
  {"name": "Alice", "age": 25, "city": "Tokyo"},
  {"name": "Bob", "age": 30, "city": "Osaka"}
]

orient でデータの向きを指定する

JSON の構造はさまざまなパターンがあり、orient 引数でどの形式かを明示できます。

records辞書のリスト(デフォルト)
columns列名をキーとした辞書
indexインデックスをキーとした辞書
splitcolumns / index / data を分割
values値のみの二次元配列
df = pd.read_json("data.json", orient="records")

API のレスポンスが辞書形式で返ってくる場合は orient=“index” や orient=“columns” を試してみてください。

文字列から直接読み込む

ファイルではなく、文字列として取得した JSON を読み込むこともできます。

import io

json_str = '[{"name": "Alice", "age": 25}, {"name": "Bob", "age": 30}]'
df = pd.read_json(io.StringIO(json_str))
print(df)

API のレスポンスをそのまま DataFrame に変換したいときに便利な書き方です。

to_json で JSON に書き出す

DataFrame を JSON として保存するには to_json を使います。

df = pd.DataFrame({
    "name": ["Alice", "Bob"],
    "age": [25, 30]
})
df.to_json("output.json", orient="records", force_ascii=False, indent=2)

force_ascii=False を指定すると、日本語などの非 ASCII 文字がエスケープされずにそのまま出力されます。indent を指定すれば人間が読みやすい整形済みの JSON になります。

read_json

JSON ファイルや文字列を DataFrame に変換する。orient でデータの向きを指定できる

to_json

DataFrame を JSON 形式で保存する。force_ascii=False で日本語をそのまま出力できる

ネストした JSON を扱う

API のレスポンスにはネストされた構造が含まれることもあります。その場合は json_normalize を使ってフラットな DataFrame に変換できます。

import json

data = [
    {"name": "Alice", "address": {"city": "Tokyo", "zip": "100-0001"}},
    {"name": "Bob", "address": {"city": "Osaka", "zip": "530-0001"}}
]
df = pd.json_normalize(data)
print(df)

ネストされた address の中身が address.city、address.zip という列名で展開されます。複雑な JSON 構造を扱うときには read_json よりも json_normalize のほうが柔軟に対応できるでしょう。