概要(pandas.read_jsonは「JSONを表に変換する入口」)
pandasのread_jsonは、JSON文字列・ファイル・URLなどを読み込み、分析しやすいDataFrameへ変換する関数です。Web APIが返すJSONをそのまま扱えるようになり、CSVと同じ感覚で前処理や集計へ進めます。向き(orient)を正しく指定すると、レコード配列や辞書型など多様なJSON構造に対応できます。
基本の使い方(文字列・ファイル・URLから読み込む)
JSON文字列をDataFrameへ
import pandas as pd
json_str = """
[
{"ID": 1, "Name": "Alice", "Score": 85},
{"ID": 2, "Name": "Bob", "Score": 92}
]
"""
df = pd.read_json(json_str) # レコード配列ならそのまま列に展開される
print(df)
# ID Name Score
# 0 1 Alice 85
# 1 2 Bob 92
PythonJSON文字列を直接渡せます。レコード志向(配列内にレコードの辞書が並ぶ)なら直感的に列へ展開されます。
ファイル・URLを指定して読み込む
# ファイル
df_file = pd.read_json("data.json")
# URL(APIやWeb上のJSON)
df_url = pd.read_json("https://example.com/api/users.json")
PythonファイルパスやURLもそのまま渡せます。Web由来のJSONをDataFrameに変換して分析へ繋げられます。
orientの深掘り(JSONの“向き”を合わせるのが重要)
なぜorientが必要か
JSONには「配列のレコード」「キーが列名の辞書」など複数の表現があります。read_jsonはデフォルトでcolumns志向を想定するため、配列レコードの場合はorient=’records’を指定すると意図どおりの表になる、というのが最重要ポイントです。
よく使う設定例
import pandas as pd
# 1) レコード志向(配列内に辞書が並ぶ)
json_records = """
[
{"name": "Apple", "price": 120},
{"name": "Banana", "price": 80}
]
"""
df_records = pd.read_json(json_records, orient="records") # 行=レコード
print(df_records)
# 2) columns志向(列名→値配列の辞書)
json_columns = """
{
"name": ["Apple", "Banana"],
"price": [120, 80]
}
"""
df_columns = pd.read_json(json_columns, orient="columns") # 列=キー
print(df_columns)
Python配列レコードはrecords、列ごとの配列はcolumnsを指定します。構造に合わせるだけで整った表になります。
ネスト構造への対処(json_normalizeでフラット化する)
read_jsonだけで難しい場合の基本戦略
入れ子のJSON(例えば「details」フィールドがさらに辞書を持つなど)は、read_jsonだけだと列がそのまま辞書になって扱いづらいことがあります。その場合は一旦読み込んだ後にpandas.json_normalizeでフラット化すると扱いやすくなります。
例:shops[].detailsを展開する
import pandas as pd
json_nested = """
{
"shops": [
{"name": "Mac", "details": {"location": "Tokyo", "type": "Burger"}},
{"name": "KFC", "details": {"location": "Osaka", "type": "Chicken"}}
]
}
"""
# まず読み込む
df_raw = pd.read_json(json_nested)
# "shops"の配列を正規化(フラット化)
df_flat = pd.json_normalize(df_raw["shops"])
print(df_flat)
# name details.location details.type
# 0 Mac Tokyo Burger
# 1 KFC Osaka Chicken
Pythonjson_normalizeは配列や辞書をドット記法の列へ展開してくれるため、集計やフィルタが簡単になります。
実践例(初心者がつまずきやすい所を具体コードで解消)
例1:APIのレコード配列をそのまま表へ
import pandas as pd
# APIレスポンス(例)
payload = """
[
{"id": 1, "name": "Taro", "active": true},
{"id": 2, "name": "Hanako", "active": false}
]
"""
# “配列のレコード”なので orient='records' が安全
users = pd.read_json(payload, orient="records")
print(users)
# id name active
# 0 1 Taro True
# 1 2 Hanako False
# 前処理:有効ユーザーだけに絞る
active_users = users[users["active"]].copy()
active_users["id"] = active_users["id"].astype(str)
active_users["name"] = active_users["name"].str.strip()
print(active_users)
Pythonレコード配列はorient=’records’で迷わず展開できます。その後の型変換・文字列整形もpandasの列操作で簡単です。
例2:列名→値配列の辞書を読み込む
import pandas as pd
data = """
{
"date": ["2025-01-01", "2025-01-02"],
"sales": [150, 200]
}
"""
df = pd.read_json(data, orient="columns") # デフォルトでもOK
df["date"] = pd.to_datetime(df["date"])
print(df)
# date sales
# 0 2025-01-01 150
# 1 2025-01-02 200
Pythoncolumns志向はデフォルト挙動に合致します。日時列はpandasのto_datetimeで変換して扱いやすくします。
例3:ネストを正規化して分析用に整える
import pandas as pd
nested = """
[
{"id": 1, "profile": {"name": "Taro", "city": "Tokyo"}},
{"id": 2, "profile": {"name": "Hanako", "city": "Osaka"}}
]
"""
df = pd.read_json(nested, orient="records")
df_norm = pd.json_normalize(df.to_dict(orient="records"))
print(df_norm)
# id profile.name profile.city
# 0 1 Taro Tokyo
# 1 2 Hanako Osaka
# 列名を簡単にする
df_norm = df_norm.rename(columns={"profile.name": "name", "profile.city": "city"})
print(df_norm[["id", "name", "city"]])
Pythonネストをそのまま列に残すより、json_normalizeで展開→列名リネームで使いやすい表に整えるのが定石です。
つまずき対策(これだけ覚えれば安心)
「レコード配列はorient=’records’」を最初に試す
JSONが[ {…}, {…} ]の形ならrecordsで読み込む。意図しない縦横になる、列がうまくできない、といった典型的なハマりを避けられます。
ネストはread_json後にjson_normalizeで展開
階層構造を無理に一発で表にしようとせず、「まず読み込む→必要な配列・辞書を正規化する」二段構えが確実です。
文字コード・型・日時の整形を早めに行う
- 文字列の前後空白はstr.strip
- 数値はastypeで型を揃える
- 日付はto_datetimeで時系列に変換 この“最初の整形”が後の集計・可視化を安定させます。
まとめ(構造に合わせてorient、ネストは正規化)
pandas.read_jsonは、JSONをDataFrameへ変換する最短ルートです。まずJSONの構造を見て、レコード配列ならorient=’records’、列志向ならデフォルトで読み込む。入れ子はjson_normalizeでフラット化して列に落とす。これだけでWeb APIや設定ファイルのJSONを、pandasの強力な前処理・分析パイプラインへ自然に載せられます。

