論文一覧に戻る 📚 用語集トップ 🗺 概念マップ
📚 用語解説
📚 用語解説
JSON
JavaScript Object Notation
データエンジニアリング

🔖 キーワード索引

JSON構造化データJSON SchemaJSON Lines浮動小数精度APICSV比較SSDSE-B-2026e-Stat演習

json」は統計データ分析の文脈で扱う重要概念のひとつ。 本ページでは「json」を取り巻く中核キーワードを以下にチップで一覧化する。 各キーワードは関連する概念・手法・道具立てを含み、 文献検索や学習計画の起点になる。

json統計分析SSDSE-B-2026前提条件適用範囲落とし穴関連手法Python 実装検証方法

これらのキーワードは「json の理解 → 適用 → 検証」のプロセスを構成する。 各章で詳しく解説する。

💡 30秒で分かる結論

🍰 まずはやさしく

データのやり取りに使う共通の形式です。

データを軽くして速く送るために使います。

スマホアプリの通信などで使われています。

ここではJSONを扱う時の注意点を読みます。

構造化データの軽量交換フォーマット

💡 最終 Tips — JSON を確実に扱う 10 ヶ条

  1. 日本語データには必ず ensure_ascii=False
  2. 大きな整数 (18 桁以上の ID) は文字列で送る。
  3. 金額は整数 (銭単位) か文字列で。 float は精度問題あり。
  4. 日付は ISO 8601 文字列 (例: "2023-12-31T23:59:59Z")。
  5. 欠損は null。 NaN や Infinity は JSON 標準外なので注意。
  6. 巨大 JSON は NDJSON か ijson でストリーミング処理。
  7. API は JSON Schema で入力検証を必ず行う。
  8. 本番では indent なしでミニファイ、 開発時は indent=2 で見やすく。
  9. 圧縮 (gzip) で通信量を 1/5〜1/10 に。
  10. セキュリティ: eval 禁止、 サイズ制限、 schema 検証で防御。

🧰 JSON ライブラリ完全比較 (Python)

ライブラリ速度datetime対応NaN対応推奨用途
json (標準)普通×○(設定で)教育・汎用
orjson超高速○ネイティブ×(オプション)本番API
ujson高速××レガシー
simplejson普通×Decimal対応
rapidjson高速スキーマ検証
ijson遅いがメモリ少××巨大JSON処理

学習用は json (標準)、 本番なら orjson、 大規模ストリーミングは ijson、 と覚えるのが楽。

📝 補遺 — 受講生からの追加質問

✅ JSON ファイル品質チェックリスト

このチェックリストを通すだけで、 JSON 関連のバグの 9 割は防げます。

🧠 さらに深掘り — JSON と他言語のオブジェクト

JSON は JavaScript 由来ですが、 各言語でほぼ同じ概念に対応します: Python の dict/list/str/int/float/bool/None、 Ruby の Hash/Array/...、 Java の Map/List/String/Integer/...、 Go の map/slice/string/int/float64/bool/nil。 この「共通基盤」が JSON 普及の核心です。

SSDSE-B-2026 のような統計データを JSON 化することで、 Python・R・JavaScript・Java など、 どの言語からも同じデータを扱えるようになります。 これが「言語非依存のデータ交換フォーマット」としての JSON の価値。 CSV にはない型情報があり、 XML にはない簡潔さがあります。

JSON を「言語横断データ表現」と捉えると、 データサイエンスの世界における位置づけが明確になります。 統計データはまず CSV で配布されますが、 アプリ統合・API 化・分析パイプライン化のいずれの段階でも JSON は必ず登場します。 SSDSE-B を「CSV→JSON→DB→API」の流れで扱えるようになれば、 公的統計を中心とした実用データサイエンスの全体像が掴めます。

🎬 SSDSE-B-2026 完全 JSON 化サンプル

本セクションでは「47 都道府県 × 12 年 × 約 110 変数」 を全て含む大きな JSON を生成する完全例を示します。 これがあれば、 別言語からも SSDSE-B のデータを呼び出せます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import json
import pandas as pd

# 1. CSV 読み込み
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', header=1)
print(f'読み込み完了: {df.shape}')

# 2. metadata セクション
metadata = {
    'name': 'SSDSE-B-2026',
    'description': '都道府県別社会・人口統計データ (Standardized Statistical Data Set for Education Series-B)',
    'source': '独立行政法人 統計センター',
    'license': 'CC BY 4.0',
    'years': sorted(df['年度'].unique().tolist()),
    'prefectures': sorted(df['都道府県名'].unique().tolist()),
    'variables': df.columns.tolist(),
    'total_records': len(df),
    'generated_at': pd.Timestamp.now().isoformat(),
}

# 3. data セクション (年度 × 都道府県のネスト)
data_by_year = {}
for year in metadata['years']:
    sub = df[df['年度']==year]
    data_by_year[str(year)] = sub.set_index('都道府県名').drop(columns=['年度']).to_dict(orient='index')

out = {
    'metadata': metadata,
    'data': data_by_year,
}

# 4. ファイル書き出し (整形あり)
with open('outputs/ssdse_b_full.json','w',encoding='utf-8') as f:
    json.dump(out, f, ensure_ascii=False, indent=2)

# 5. ファイル書き出し (ミニファイ、 本番用)
with open('outputs/ssdse_b_full.min.json','w',encoding='utf-8') as f:
    json.dump(out, f, ensure_ascii=False, separators=(',', ':'))

# 6. NDJSON 書き出し (1行1都道府県)
with open('outputs/ssdse_b.ndjson','w',encoding='utf-8') as f:
    for _, row in df.iterrows():
        f.write(json.dumps(row.to_dict(), ensure_ascii=False, default=str) + '
')

print('完了')
print(f'整形JSON  : outputs/ssdse_b_full.json')
print(f'ミニJSON  : outputs/ssdse_b_full.min.json')
print(f'NDJSON    : outputs/ssdse_b.ndjson')

これで SSDSE-B の全データが 3 形式の JSON として保存され、 各種ツール (JavaScript, Java, Go, R, Julia など) から再利用できる状態になります。

🌟 結び — JSON は「ただのフォーマット」ではない

JSON は表面的には「{} と [] と : と , と "" だけのテキスト」ですが、 その背後には「言語横断の共通モデル」という哲学があります。 Python の dict、 JavaScript の Object、 Java の Map、 Go の map ─ 全ての主要言語が同じ概念を持つことで、 JSON はそれらをつなぐ橋として機能します。

SSDSE-B-2026 を CSV で読み、 JSON に変換し、 NDJSON でストリーミングし、 NoSQL に投入し、 API として配信し、 Schema で検証する ─ この一連の流れを自由に行えるようになれば、 公的統計を中心とした実用データサイエンスの基盤がほぼ完成します。 「データを語る言語」としての JSON を、 ぜひ自分の道具として身につけてください。

📦 JSON 圧縮・分割・配信の実務

100 MB を超える JSON を扱うとき、 単一ファイルは非効率です。 「日付別」「都道府県別」「カテゴリ別」のいずれかでパーティショニングするのが定番。 SSDSE-B のような時系列データなら「年度別ディレクトリ + NDJSON」が扱いやすい形:

📥 入力例(SSDSE-B-2026 の 2023 年・47 都道府県から 3 行) 都道府県 SSDSE-B-2026(年度) 北海道 2,023 東京都 2,023 沖縄県 2,023 …(全 47 行)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
# ── この抜粋で使うデータを用意します ──
import os, gzip, json
import pandas as pd

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', header=1)

os.makedirs('outputs/partitioned', exist_ok=True)
for year, sub in df.groupby('年度'):
    path = f'outputs/partitioned/year={year}/data.ndjson.gz'
    os.makedirs(os.path.dirname(path), exist_ok=True)
    with gzip.open(path, 'wt', encoding='utf-8') as f:
        for _, row in sub.iterrows():
            f.write(json.dumps(row.to_dict(), ensure_ascii=False, default=str) + '\n')
print('作成したディレクトリ:', sorted(os.listdir('outputs/partitioned'))[:3], '...')
# year=2012/, year=2013/, ..., year=2023/ のディレクトリ構造
# Hive 互換のパーティション形式で BigQuery 等から直接クエリ可
📤 実行例(実測) 作成したディレクトリ: ['year=2012', 'year=2013', 'year=2014'] ...

この形式は AWS S3 / Google Cloud Storage に置けば、 Athena / BigQuery から SQL で集計可能。 SSDSE-B 程度の小データなら単一ファイルで十分ですが、 数十 GB に膨れたときの対処法として覚えておく価値があります。

🎓 演習解答例 — 演習1 を完全解説

演習1: SSDSE-B-2026 を読み込み、 2023 年の 47 県データを data/processed/ssdse_b_2023.json として保存せよ。

📥 入力例(SSDSE-B-2026 の 2023 年・47 都道府県から 3 行) 都道府県 SSDSE-B-2026(年度) A1303(65歳以上人口) A1101(総人口) Prefecture(都道府県) 北海道 2,023 1,681,000 5,092,000 北海道 東京都 2,023 3,205,000 14,086,000 東京都 沖縄県 2,023 350,000 1,468,000 沖縄県 …(全 47 行)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import pandas as pd
import json
import os

# 1. CSV 読み込み
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=1)
# 2. 2023年でフィルタ
df23 = df[df['年度']==2023].copy()
# 3. 必要列を選択 + 高齢化率を派生列に
df23['高齢化率'] = (df23['65歳以上人口'] / df23['総人口'] * 100).round(2)
# 実際の列名は「都道府県名」ではなく「都道府県」
df23 = df23[['地域コード','都道府県','総人口','65歳以上人口','高齢化率']]
df23.columns = ['code','prefecture','population','aged_pop','aged_ratio']
# 4. JSON 構造を作る
out = {
    'metadata': {
        'source': 'SSDSE-B-2026',
        'year': 2023,
        'rows': len(df23),
        'columns': df23.columns.tolist(),
        'total_population': int(df23['population'].sum()),
        'mean_aged_ratio': round(df23['aged_ratio'].mean(), 2),
    },
    'data': df23.to_dict(orient='records'),
}
# 5. 保存
os.makedirs('data/processed', exist_ok=True)
with open('data/processed/ssdse_b_2023.json','w',encoding='utf-8') as f:
    json.dump(out, f, ensure_ascii=False, indent=2)
print('保存完了: data/processed/ssdse_b_2023.json')

# 検証
with open('data/processed/ssdse_b_2023.json',encoding='utf-8') as f:
    loaded = json.load(f)
assert loaded['metadata']['rows'] == 47
assert len(loaded['data']) == 47
print('検証 OK')
📤 実行例(実測) 保存完了: data/processed/ssdse_b_2023.json 検証 OK

この一連のコードは、 「読み込み → 加工 → 構造化 → 保存 → 検証」 の流れを完備しており、 他の演習でも同じ骨格を使い回せます。

📍 文脈 ── どこで出会うか

🍰 まずはやさしく

データの受け渡しに使う共通のルールです。

ネット上のデータを集めるために使います。

統計サイトからデータを取る時に出会います。

どんな場面でJSONが登場するかを読みます。

JSON は Web API のレスポンス、 e-Stat の統計データ取得、 設定ファイル (package.json, .vscode/settings.json)、 NoSQL データベース (MongoDB) などあらゆる場面で登場します。 SSDSE-B-2026 は CSV 配布ですが、 同じデータを e-Stat の API で取得すると JSON 形式で返ります。 つまり「同じ統計データを 2 つのフォーマットで扱う」基礎技能としても、 JSON は必須知識です。

🎨 直感で掴む

🍰 まずはやさしく

データの整理棚のような仕組みです。

分析しやすい形に整えるために使います。

部活の名簿を整理する感覚に似ています。

JSONの構造や使い方のコツを読みます。

データを「分析・モデリングに使える形に整える」工程。 分析の質はここで 8 割決まります。

本ページでは JSON を、 定義・前提条件・使い方・落とし穴の順に整理して解説します。 厳密な定義より、 まず何を、 いつ、 どう使うかを理解することを優先してください。

🎨 概念図で押さえる — JSON の3つの視点

JSON の理解には、 (1) 階層構造の木表現 (オブジェクト/配列のネスト)、 (2) スキーマ検証時の分布チェック、 (3) 統計データとの相関構造保持 の 3 点を同時に把握する必要があります。 ここでは html/glossary/figures/ にある既存図を借りて、 JSON データ処理のキャンバスを描き出します。

決定木の構造
図A: 決定木の図は、 JSON の階層構造をそのまま視覚化する優れた比喩。 ルートが { }、 各ノードがキー、 リーフが値 (string/number/boolean) に対応する。 SSDSE-B-2026 の都道府県データを JSON 化すると、 {"prefectures": [{"name": "北海道", "pop": ..., "stats": {...}}, ...]} のような木構造になる。 分岐の深さがネスト深度、 兄弟ノードが同じ階層の要素を表す。 jq や JSONPath での参照パスは、 まさにこの木を上から辿る経路指定である。

読み取るポイント:

  • 木の深さ → ネスト階層数、 深すぎると参照が複雑化
  • 分岐数 → 配列要素数、 1000 件超ならストリーミング解析を検討
  • リーフの型混在 → 型安全性が壊れるサイン、 JSON Schema で検証
散布図(基本)
図B: JSON 内の数値フィールドを散布図にすると、 構造化データとしての品質が一目で分かる。 例えば {"pop": ..., "gdp": ...} の関係を散布図化し、 強い相関が確認できれば、 スキーマ設計時に正規化が必要かを判断できる。 SSDSE-B-2026 を JSON 化した後、 pandas で pd.json_normalize() し、 散布図でデータ整合性をチェックするのが標準フロー。 異常値や型崩れも散布図で検知しやすい。

読み取るポイント:

  • 線形関係 → 派生フィールドの可能性、 冗長性を疑う
  • 外れ値 → JSON 中のデータ品質問題、 入力検証強化
  • クラスタ分離 → カテゴリ分割の手がかり、 配列ネストで表現
ヒストグラム(基本)
図C: JSON の数値配列を集計してヒストグラムにすると、 元データの分布特性が JSON 化後も保たれているかを検証できる。 たとえば "populations": [..., ..., ...] という配列を取り出し、 ヒストグラムで分布が右偏 (右に裾) なら正しい人口データ。 これがフラットに見えるなら型変換ミス (文字列→数値の失敗) を疑う。 JSON Schema の "type": "number" 検証と並行して、 必ず分布チェックを行う。

読み取るポイント:

  • 分布形状が元データと一致 → JSON 化成功
  • 分布が崩れる → 型変換エラー、 シリアライズ設定を見直す
  • 欠損が増えた → null 値の処理ミス、 default 値の見直し

この 3 枚を順に追うと、 「構造把握 → 関係性確認 → 分布検証」 という JSON データ品質チェックのフローが体系化される。 関連用語 API / CSV / データクレンジング へ進むと、 各図の理論背景を深掘りできる。

🎨 概念図で押さえる

JSON 解析後の典型的な可視化フロー(分布 → 散布 → 構造)を、 SSDSE 由来の参照図で確認する。 これらは JSON から DataFrame に変換した後の品質チェックや関係性把握に使われる定番図。

ヒストグラムの基本形(数値項目の分布確認)
JSON から取り出した数値配列のヒストグラム。 値域・歪み・外れ値の把握に直結。
散布図の基本形(2 項目の関係性)
ネストされた JSON フィールド同士の関係を散布図で。 階層構造の意味確認に有効。
相関行列ヒートマップ
JSON フラット化後の数値列で相関行列を作成。 重複情報や強い従属関係を一覧で把握。

→ JSON は構造データだが、 解析の本質は「数値列の分布と関係性の確認」。 ヒストグラム・散布図・相関行列の 3 点セットで、 ほとんどの初期 EDA は完了する。

✅ 理解度チェック

  1. JSON と CSV の最大の違いは何か? (ヒント:階層構造の有無)
  2. json.loads()json.dumps() の役割をそれぞれ 1 行で説明できるか?
  3. ネストされた JSON を pandas DataFrame に変換する関数は? (ヒント:pd.json_normalize
  4. JSON の null は pandas で何に変換されるか?
  5. API レスポンスを保存するとき、 JSON と JSONL のどちらが追記に向くか? 理由は?

→ すべて即答できれば、 JSON を実務でハンドリングする基礎力は十分。 不安な項目は本ページの該当セクションを再読すること。

🖼 視覚資料: 構造化データの俯瞰

JSON は SSDSE-B などの構造化データを階層・行列として扱う基盤フォーマット。 ここでは関連する 3 つの視覚資料で「データ全体の形」を再確認する。

パネルデータ構造
パネル/階層データの典型構造。 JSON でネストすると表現が直感的
相関ヒートマップ
JSON でしばしばやり取りする集計結果の一例(4 変数の相関行列)
ヒストグラム
JSON 配列を pandas に展開してから可視化した分布の例

🖼 補足: JSON データを可視化で検証する 3 段階

JSON を扱うときに最も重要なのは、 「シリアライズ → デシリアライズ → 解析」 の過程で情報が失われていないかを確認することです。 ここでは SSDSE-B-2026 由来の数値を JSON 経由で取り扱った後の確認手段を、 3 つの定番図で説明します。

JSON 配列のヒストグラム化
図1: JSON の数値配列 (例: "population": [...]) を pandas に展開し、 ヒストグラムで分布を確認する。 元 CSV と分布が一致すれば JSON 化は成功。 ヒストグラムが平坦化したり、 ピークが消えたりしたら、 文字列としてシリアライズされた数値が混入している可能性が高い。 これは json.dump(..., default=str) の副作用としてよく発生する。
JSON 数値フィールドの散布図
図2: 同じ JSON ドキュメント内の数値フィールド同士を散布図化する。 {"gdp": ..., "pop": ...} のような構造から散布図を作ると、 ドメイン的に意味のある相関 (人口 ↔ GDP の正相関) が再現されているかを確認できる。 散布図に異常なクラスタや境界線が出る場合は、 ネスト構造を pd.json_normalize で展開する際の階層エラーを疑う。
JSON フラット化後の相関ヒートマップ
図3: JSON をフラット化した後の数値列 4 つで相関行列を描くと、 「ネストした構造の冗長性」 や 「JSON Schema 設計上の正規化漏れ」 が見える。 強い相関 (|r|>0.9) のペアが多すぎる場合は、 派生フィールドが冗長に含まれているサイン。 API 設計を見直し、 計算で求められるものは省くべき。

この 3 図のチェックを毎回必ず挟むだけで、 JSON 由来のデータ品質バグは 80% 以上検知できます。 とくに API クライアントから取得した JSON は、 サーバー側のバグ・型変換ミス・スキーマ更新の取りこぼしが混入しやすく、 分布検証なしで分析を始めると後工程で結論を覆すコストを支払うことになります。

確認段階使う図検知できる問題対応
単変量分布ヒストグラム型崩れ、 文字列混入、 欠損増加dtype 検査、 NaN 集計
2 変量関係散布図ネスト構造の展開ミス、 行のずれjson_normalize 経路再確認
多変量俯瞰相関ヒートマップ冗長フィールド、 派生指標の重複スキーマ正規化、 派生列を除外

これら 3 図はそれぞれ単純な可視化ですが、 「JSON のシリアライズが情報量を保存できているか」 という根本的な品質確認を、 視覚的かつ網羅的に行える手段として実務で重宝されます。 とくに e-Stat 風 API や社内 REST API を設計する際は、 受信側の最初のステップとして必ず組み込むべきチェックポイントです。

📝 補足: 実務で押さえる JSON 運用パターン

JSON は 「読み書きしやすい」 反面、 運用面の罠 が多い形式です。 ここでは公開 API・社内 API・データ永続化の 3 シーンで頻出する運用パターンを、 実データを念頭に整理します。

パターン A: 公開 API としての JSON

e-Stat、 政府統計、 自治体 API などはほぼ JSON で提供されます。 SSDSE-B-2026 を pd.json_normalize で取得した後、 必ず df.dtypes でカラム型を確認しましょう。 とくに人口・面積などの数値が object (文字列) になっている場合、 後工程の集計・可視化が静かに失敗します。 さらに JSON の null は pandas で NaN または None に変換されるため、 集計時の挙動 (mean/sum/count) を意識する必要があります。

パターン B: 社内 API としての JSON

社内マイクロサービス間で JSON を使う場合、 「JSON Schema で型を契約する」 ことが鉄則です。 Schema を書かないと、 上流のスキーマ変更が下流に伝わらず、 ある日突然 KeyError や型エラーで本番が止まります。 OpenAPI と組み合わせれば、 リクエスト/レスポンスの両方を機械的に検証でき、 ドキュメントとコードの乖離も防げます。 さらに jsonschema パッケージで CI に組み込み、 PR 時点でスキーマ違反を検知する運用が安全です。

パターン C: 長期保存・解析データセット

JSON を直接データレイクに置く運用は非推奨です。 大規模化すると JSON はパース速度・サイズ効率で Parquet/ORC に大きく劣ります。 暫定保存には NDJSON (1 行 1 JSON) + gzip を使い、 解析段階では Parquet に変換するハイブリッド戦略が一般的。 SSDSE-B-2026 規模 (47 県 × 110 列) なら JSON 直置きでも問題ありませんが、 数年分の積算で時系列化する場合は早い段階で Parquet 化を検討すべきです。

シーン推奨フォーマット理由注意点
公開 APIJSON (UTF-8)クライアント互換性、 ブラウザネイティブ数値型崩れ、 null 仕様
社内サービス間JSON + Schema 検証柔軟性と型契約の両立スキーマ更新の同期
大規模解析Parquet / Arrow列指向で速く、 圧縮効率も高い人間可読性の喪失
ストリーミングNDJSON (JSON Lines)追記しやすい、 部分読みやすい配列としては読めない

これらのパターンを使い分ける感覚は、 1 度プロダクションで JSON のスキーマ変更事故を経験すると一気に身につきます。 平常時の予防として、 必ず最初に分布チェック・型チェック・スキーマ検証の 3 点セットを入れる癖をつけてください。

追加 Tips: JSON と日本語データ

日本語を含む JSON では、 ensure_ascii=True (Python の json.dump のデフォルト) のままにすると、 都道府県名や注釈が 京都 のようにエスケープされ、 ファイルサイズが約 2 〜 3 倍に膨らみます。 SSDSE-B-2026 の都道府県カラムを JSON 化する場合は、 ほぼ確実に ensure_ascii=False + UTF-8 ファイル書き出し (open(path, 'w', encoding='utf-8')) の組み合わせを使うべきです。 逆に、 古い Windows 環境や厳格な ASCII-only API では、 デフォルトのままの方が安全な場合もあります。 「文字コードはどこで決まるか」を意識せずに JSON を回すと、 数年後に文字化けでデータが復元不可能になる事故が起きるため、 必ずヘッダ・ファイル・通信経路の 3 段階で UTF-8 を統一する運用にしてください。

また日本語キー (例: {"都道府県": "東京都"}) も RFC 8259 上は合法ですが、 多くの JSON Schema バリデータ・OpenAPI ジェネレータが正しく扱えないケースがあり、 推奨はキーは ASCII、 値は日本語可のパターンです。 これは SSDSE-B-2026 の CSV を JSON 化する際の暗黙のルールとして覚えておきましょう。

追加 Tips: JSON とパフォーマンス

標準ライブラリの json モジュールは便利ですが、 数十万件規模になるとパース速度が体感で詰まってきます。 orjsonujson は C/Rust 実装で 5 〜 10 倍速く、 とくに orjsondatetimenumpy 配列・dataclass を直接シリアライズできるため、 SSDSE-B-2026 のような数値ばかりの DataFrame を JSON 化する用途では強力です。 ただし orjson は厳格な RFC 準拠で、 標準 json が許容する一部の非標準 (NaNInfinity) を拒否するので、 既存パイプラインを単純置換すると例外が出る場合があります。

さらに数百 MB を超える JSON は ijson によるストリーミングパース、 または NDJSON で 1 行ずつ json.loads する戦略が現実的です。 1 ファイル全体を json.load(f) でメモリに読み込もうとすると、 RAM の数倍を消費してプロセスが落ちる典型的なバグになります。 規模が見えない JSON はストリーミングで読む を第一手にしてください。 SSDSE-B-2026 規模なら一括読み込みで問題ありませんが、 e-Stat 全テーマ × 全年度を 1 ファイルに束ねる場合は数 GB に到達し、 一括読み込みは現実的でなくなります。

最後に、 JSON のサイズ最適化として indent=None (改行・スペースなし) でシリアライズすると、 SSDSE-B-2026 の 1 県分で約 30% サイズが減ります。 人間が読まない API レスポンスではこれが標準。 デバッグ用には indent=2 を使い、 本番では indent=None + separators=(',', ':') を選ぶことで、 通信量を最小化できます。

JSON を学ぶ次のステップ

本ページで JSON の基礎構造・読み書き・パフォーマンス・運用パターンを押さえました。 次に学ぶべきは JSON Schema (型契約の言語)、 OpenAPI 3.x (REST API の設計仕様)、 そして JSON-LD (Semantic Web・Schema.org への対応) です。 これらを順に押さえると、 単に 「JSON を読み書きする」 段階から、 「JSON を中心に API・データ基盤・SEO まで設計する」 段階に進めます。

並行して、 APICSVデータクレンジングDataFrame の各用語ページを巡回すると、 「JSON で受け取る → DataFrame で整形 → クレンジング → 集計」 という一連の流れを体系的に理解できます。 SSDSE-B-2026 の小規模データでこのフローを 1 周通すことが、 実務に直結する最短経路です。

最後に、 JSON を 「単なるデータ転送フォーマット」 と捉えるのではなく、 「世界中の API・ログ・設定ファイルの共通言語」 として捉えることをお勧めします。 そう捉えると、 JSON Schema・OpenAPI・JSON-LD・NDJSON といった派生規格を学ぶ動機が明確になり、 自分の手で 「API を設計する側」 に回るための道筋が見えてきます。 SSDSE-B-2026 から取り出した数値を、 JSON 経由で世界へ発信する力を、 ぜひこのページから身につけてください。 そしてその先には API 設計者・データエンジニアとしての具体的なキャリアパスが広がっています。

📐 定義

🍰 まずはやさしく

データの書き方を決めた世界共通の形式です。

データを正しく伝える道具として使います。

プログラミングの学習などでよく使われます。

JSONの定義と使う時の条件について読みます。

構造化データの軽量交換フォーマット

英語名 JavaScript Object Notation

🎯 いつ・どこで使うか

📋 前提条件・適用範囲

この用語を理解・使用するときは、 次のような前提を意識してください:

🔬 JSON Schema、 JSON Lines、 関連フォーマット

🔬 JSON Schema、 JSON Lines、 関連フォーマット

JSON Schema による検証

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# JSON Schema で型と必須項目を検証
import jsonschema, json

schema = {
  "type": "object",
  "properties": {
    "data": {
      "type": "array",
      "items": {
        "type": "object",
        "required": ["code","prefecture","population"],
        "properties": {
          "code":       {"type":"string","pattern":"^R\d{5}$"},
          "prefecture": {"type":"string"},
          "population": {"type":"integer","minimum":0},
          "aged_pop":   {"type":"integer","minimum":0},
          "aged_ratio": {"type":"number","minimum":0,"maximum":100}
        }
      }
    }
  }
}

with open('ssdse_b_2023.json',encoding='utf-8') as f:
    data = json.load(f)
jsonschema.validate(data, schema)
print('Schema OK')
📤 実行例(実測) Schema OK

JSON 系派生フォーマット

フォーマット特徴用途
JSON標準Web API
JSON Lines (NDJSON)1 行 1 オブジェクトBigQuery, ログ
JSON5コメント・末尾カンマOK設定ファイル
BSONバイナリ JSONMongoDB
MessagePackコンパクトモバイル通信
JSON-LDリンクトデータSchema.org, SEO

JSON は数式ではなくデータ構造ですが、 形式言語として厳密な文法 (BNF) を持ち、 再帰的な定義として読み解けます。 RFC 8259 で定義された JSON のグランマールは以下のように再帰的に表現できます: $$\textit{value} \to \textit{object}\ |\ \textit{array}\ |\ \textit{string}\ |\ \textit{number}\ |\ \textit{boolean}\ |\ \textit{null}$$ $$\textit{object} \to \{\ \textit{string}\ :\ \textit{value},\ \dots\ \}$$ $$\textit{array} \to [\ \textit{value},\ \textit{value},\ \dots\ ]$$ この 6 種類の基本型と 2 種類のコンテナ (object / array) の組み合わせだけで、 任意の階層的データを表現します。 シンプルさが普及の最大要因です。

要素1: プリミティブ型 6 種類

JSON の基本型はstring (UTF-8 のテキスト、 ダブルクォート必須)、 number (整数・浮動小数、 ただし NaN/Infinity 非対応)、 boolean (true / false)、 null (欠損)、 object (キー=string の連想配列)、 array (順序付きリスト) の 6 種類のみ。 これは Python の int/float/str/bool/None/dict/list に概ね対応します。 注意点として、 JSON には日付型がないため、 慣習的に ISO 8601 文字列 (例: "2023-12-31T23:59:59Z") を使います。 また、 JavaScript の Number は 2^53-1 までしか整数を厳密に表現できないため、 64-bit ID(マイナンバーや Twitter Snowflake ID)は string で送るのが安全です。

要素2: object — キー・値の連想配列

object は {"key1": value1, "key2": value2} の形式で、 キーは必ず string、 値は任意の type。 「キーの順序は保証されない」のが標準 (Python の dict は 3.7+ で挿入順保証だが、 JSON 仕様としては不定)。 SSDSE-B-2026 を JSON で表現するなら、 {"prefecture":"東京都", "population":14086000, "aged_ratio":22.75} のように、 1 都道府県を 1 object で表します。 object はネスト可能で、 {"metadata":{"year":2023,"source":"SSDSE"}} のように階層構造を任意に深くできます。

要素3: array — 順序付きリスト

array は [value1, value2, value3] で、 順序が保持され、 異なる型を混在可能。 47 都道府県を JSON で持つなら "data": [{"prefecture":"北海道",...}, {"prefecture":"青森県",...}, ...] のように 47 個の object を array に並べます。 array の要素は同一構造である必要は無いが、 実務的にはスキーマを統一する方が後段の処理が楽。 SSDSE のような「同質的なレコード集合」は array of objects のパターンで表現するのが定石です。

要素4: 再帰的なネスト — 任意の階層

value は再帰的に object / array を含めるため、 任意の深さの階層構造が表現可能。 例: {"data":[{"prefecture":"東京都","subregions":[{"name":"23区","pop":9700000},{"name":"多摩","pop":4200000}]}]} のように、 都道府県の中に下位地域を入れ子にできます。 ただし、 ネストが深くなると可読性と処理速度が低下するため、 実用上は 3〜4 階層が上限。 BigQuery などの分析エンジンは深いネストを苦手とするため、 平坦化 (flatten) する場面も多い。 SSDSE-B-2026 程度のフラットなデータなら、 1 階層 (オブジェクトの配列) で十分です。

🧮 SSDSE-B-2026 を JSON 形式で表現する

🧮 SSDSE-B-2026 を JSON 形式で表現する

SSDSE-B-2026 は CSV だが、 Web API では JSON が事実上の標準。 e-Stat の API レスポンスも JSON。 同じ都道府県データを JSON 化するとこうなる:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
{
  "metadata": {
    "source": "SSDSE-B-2026",
    "year": 2023,
    "rows": 47,
    "encoding": "utf-8"
  },
  "data": [
    {"code": "R13000", "prefecture": "東京都",
     "population": 14086000, "aged_pop": 3205000,
     "aged_ratio": 22.75},
    {"code": "R01000", "prefecture": "北海道",
     "population":  5092000, "aged_pop": 1681000,
     "aged_ratio": 33.01},
    {"code": "R47000", "prefecture": "沖縄県",
     "population":  1468000, "aged_pop":  350000,
     "aged_ratio": 23.84}
  ]
}

CSV と比較した特徴:

観点CSVJSON
階層構造平坦のみネスト可
型情報全て文字列数値・真偽・null 区別
スキーマ暗黙的JSON Schema で記述可
サイズ小さいキー名繰り返しで大きい
可読性表形式向きネスト向き
Web APIファイル添付レスポンスボディ
📥 入力例(SSDSE-B-2026 の 2023 年・47 都道府県から 3 行) 都道府県 SSDSE-B-2026(年度) Prefecture(都道府県) A1101(総人口) A1303(65歳以上人口) 北海道 2,023 北海道 5,092,000 1,681,000 東京都 2,023 東京都 14,086,000 3,205,000 沖縄県 2,023 沖縄県 1,468,000 350,000 …(全 47 行)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
# pandas → JSON 変換
import pandas as pd
import json

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', header=1)
df = df[df['年度']==2023][['地域コード','都道府県','総人口','65歳以上人口']]
df.columns = ['code','prefecture','population','aged_pop']
df['aged_ratio'] = (df['aged_pop']/df['population']*100).round(2)

# orient='records' で配列の各要素が 1 都道府県
records = df.to_dict(orient='records')
out = {'metadata': {'source':'SSDSE-B-2026','year':2023,'rows':len(df)},
       'data': records}

with open('ssdse_b_2023.json','w',encoding='utf-8') as f:
    json.dump(out, f, ensure_ascii=False, indent=2)

# 読み込み
with open('ssdse_b_2023.json',encoding='utf-8') as f:
    loaded = json.load(f)
print(loaded['data'][0])  # {'code':'R01000','prefecture':'北海道',...}
📤 実行例(実測) {'code': 'R01000', 'prefecture': '北海道', 'population': 5092000, 'aged_pop': 1681000, 'aged_ratio': 33.01}

🧮 SSDSE-B-2026 を JSON に変換し API レスポンス風に扱う

🎯 このブロックの狙い
SSDSE-B-2026 (CSV) を読み込み、 metadata と data を含む構造化 JSON に変換する。 これは e-Stat API のレスポンスを模倣する形であり、 「同じデータが CSV と JSON でどう表現されるか」を体感できる。
📥 入力
data/raw/SSDSE-B-2026.csv から 2023 年の 47 都道府県データ。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import pandas as pd
import json

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=1)
df23 = df[df['年度']==2023].copy()
df23['aged_ratio'] = (df23['65歳以上人口']/df23['総人口']*100).round(2)
# 実際の列名は「都道府県名」ではなく「都道府県」
df23 = df23[['地域コード','都道府県','総人口','65歳以上人口','aged_ratio']]
df23.columns = ['code','prefecture','population','aged_pop','aged_ratio']

# JSON 構造を作る
out = {
    'metadata': {
        'source': 'SSDSE-B-2026',
        'year': 2023,
        'rows': len(df23),
        'encoding': 'utf-8',
    },
    'data': df23.to_dict(orient='records'),
}

import os
os.makedirs('outputs', exist_ok=True)   # 保存先が無いと open('w') は失敗する
with open('outputs/ssdse_b_2023.json','w',encoding='utf-8') as f:
    json.dump(out, f, ensure_ascii=False, indent=2)

# 読み戻し
with open('outputs/ssdse_b_2023.json',encoding='utf-8') as f:
    loaded = json.load(f)
print(loaded['metadata'])
print(loaded['data'][0])           # 北海道
print(loaded['data'][12])          # 東京都
print(f'全国合計 = {sum(d["population"] for d in loaded["data"]):,}')
📤 出力(期待値)
JSON ファイルは約 5-8 KB(47 県のレコード)。 全国合計は約 1.24 億人(124,353,000)。 北海道は {"code":"R01000","prefecture":"北海道","population":5092000,...}、 東京都は {"code":"R13000","prefecture":"東京都","population":14086000,"aged_ratio":22.75}
💬 解説
ensure_ascii=False が日本語を「東京都」のまま保存する鍵。 デフォルトの True だと「東京都」 になる。 また orient='records' は object の array 形式(API レスポンスの定番)。 他にも 'index''split''columns' など 6 種のフォーマットがある。

🏭 産業事例 6 件 — JSON はどこで動いているか

業界JSON の役割代表例 / 規模
Web API (一般)REST API のレスポンスフォーマットの事実上の標準。 Twitter, Stripe, GitHub, e-Stat, 気象庁すべて JSON。数 KB〜数 MB
公的統計e-Stat API は 統計データを JSON で配信。 都道府県別人口・GDP・気象データ等。 SSDSE-B も裏側は同じソース。数 KB〜数十 MB
NoSQL DBMongoDB / Couchbase は JSON ドキュメントを保存・検索する DB。 スキーマレスな柔軟性。数百GB
ログ・分析基盤BigQuery / Snowflake は JSON Lines (NDJSON) でログを取り込み。 1 行 1 オブジェクト。TB 級/日
設定ファイルpackage.json (Node.js)、 tsconfig.json、 .vscode/settings.json など、 開発ツールの設定。数 KB
機械学習モデル交換scikit-learn / Hugging Face Transformer のメタデータ、 ONNX のモデル属性は JSON で記述。数 KB〜数 MB

📊 比較表 — 主要なデータ交換フォーマット

フォーマット階層型情報サイズ人間可読用途
JSONWeb API 標準
CSV××表形式データ、 Excel
XMLスキーマ依存SOAP、 設定 (.NET)
YAML設定 (Kubernetes, GitHub Actions)
TOMLpyproject.toml、 Cargo.toml
JSON Lines (NDJSON)ログ、 BigQuery 取り込み
Parquet最小×分析、 大規模列志向
MessagePack×バイナリJSON、 高速通信
Protobuf最小×gRPC, Google 系
Avro最小×Hadoop、 Kafka

✏️ 演習 5 問 — SSDSE-B-2026 を JSON 化する

  1. 演習1: SSDSE-B-2026 を読み込み、 2023年の47県データを data/processed/ssdse_b_2023.json として保存せよ (metadata + data の構造)。
  2. 演習2: 演習1の JSON を読み戻し、 「全国総人口」と「高齢化率上位3県」を表示せよ。
  3. 演習3: 同じデータを JSON Lines (NDJSON) 形式 (1行1オブジェクト) で保存し、 ファイルサイズを通常 JSON と比較せよ。
  4. 演習4: JSON Schema を書いて、 「prefecture が string、 population が 0 以上の integer、 aged_ratio が 0-100 の number」 を検証せよ。 不正データを混ぜて意図的に失敗させよ。
  5. 演習5: 「都道府県を地域 (北海道/東北/関東/...) ごとにグループ化して、 ネストした JSON」を作成せよ (例: {"地域":"関東","都道府県":[{...},{...}]})。

💀 失敗例ケーススタディ — JSON 取り扱い事故

事例1: ensure_ascii=True で日本語が \uXXXX に

json.dump のデフォルトは ensure_ascii=True。 「東京都」を保存しても「東京都」になり、 ファイルが膨らみ可読性が消える。 対策: 必ず ensure_ascii=False を指定し、 UTF-8 で書き出す。

事例2: pandas の NaN が null に化けて気づかない

df.to_json() で NaN は null に変換される。 復号後 None として扱われるが、 集計関数 (sum, mean) の挙動が変わる。 対策: 事前に欠損方針を決め、 必要なら fillna してから JSON 化。

事例3: 64-bit ID を Number で送って精度欠落

マイナンバーや Twitter Snowflake ID のような 18 桁整数を JSON の Number として送ると、 JavaScript 側で 2^53-1 を超え末尾が丸まる。 対策: ID は文字列にキャストして送る。

事例4: コメント書いて parse エラー

JSON はコメント非対応。 設定ファイルにメモを書こうとして // comment を入れると即 parse エラー。 対策: JSON5 か YAML を使う、 もしくは "_comment": "..." 風のキーで誤魔化す。

事例5: 末尾カンマで parse エラー

JavaScript リテラルでは許容される末尾カンマが JSON では文法エラー。 手書きで JSON を整形すると頻発する事故。 対策: lint ツールで自動チェック、 または手書きを避けて json.dumps で生成。

📖 用語ミニ辞典(10語)

RFC 8259
現行の JSON 仕様。 2017 年。 厳密な構文と UTF-8 必須を定める。
JSON Schema
JSON データの型・必須項目・範囲を JSON 自身で記述する仕様。 jsonschema-validator で検証。
JSON Lines (NDJSON)
1 行 1 オブジェクトの形式。 ログ・大容量データ向け。 BigQuery が取り込める。
JSONP
Cross-domain 通信のため関数呼び出しで JSON をラップした旧手法。 現代では CORS が代替。
JSON5
コメント・末尾カンマ・シングルクォート許容の拡張。 設定ファイル向き。
JSON-LD
JSON for Linked Data。 セマンティック Web、 Schema.org、 SEO の構造化データ。
BSON
Binary JSON。 MongoDB の内部フォーマット。 日付型ネイティブ対応。
MessagePack
JSON 互換のバイナリ表現。 サイズ小・パース速い。 fluentd 等で使用。
JMESPath / JQ
JSON にクエリを発行する言語。 jq コマンドで CLI から扱える。
JSON Pointer
JSON 内の特定位置を文字列で指す仕様。 例: /data/0/prefecture = data 配列の最初の prefecture 値。

🕰 歴史的背景 — なぜ JSON は世界標準になったか

JSON は 2001 年に Douglas Crockford が公開しました。 JavaScript のオブジェクトリテラル構文をそのまま使うシンプルさが当初の特徴です。 当時は XML が事実上の標準で、 SOAP / WSDL などの重厚なプロトコルが Web API の主流でした。 しかし XML は冗長で、 ブラウザ側 JavaScript からは扱いにくい。 そこで「JavaScript で eval() するだけでオブジェクトになる」JSON が、 AJAX (2005年) ブームと共に急速に普及しました。

2006 年に RFC 4627 として標準化、 2013 年に RFC 7159、 2017 年に RFC 8259 として現行版になりました。 JSON Schema は 2009 年から開発が始まり、 現在は draft-2020-12 まで進化。 NoSQL ムーブメント (MongoDB 2009, CouchDB 2005) と相まって、 「スキーマレスで階層的なデータ」を扱う標準として完全に定着しました。

日本の e-Stat も 2014 年に API を公開し、 JSON / XML 両形式でデータを配信。 SSDSE-B-2026 のような統計データを CSV で配布する一方、 同じデータが JSON API でも取れるようになっており、 「データ取得の現代的標準」として JSON は不動の地位を占めています。

🔧 高度なレシピ — JSON を扱い倒す

レシピ1: requests で e-Stat API から JSON を取得

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
import requests
url = 'https://api.e-stat.go.jp/rest/3.0/app/json/getStatsData'
params = {
    'appId': 'YOUR_APP_ID',
    'statsDataId': '0003448237',   # 人口推計
    'cdArea': '13000',             # 東京都
    'limit': 100,
}
res = requests.get(url, params=params)
data = res.json()
print(data['GET_STATS_DATA']['STATISTICAL_DATA']['DATA_INF']['VALUE'][:3])

レシピ2: ネストした JSON を pandas に展開

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
import pandas as pd

nested = {
    'metadata': {'source':'SSDSE-B-2026','year':2023},
    'data': [
        {'prefecture':'東京都','population':14086000,'subregions':[{'name':'23区','pop':9700000},{'name':'多摩','pop':4200000}]},
        {'prefecture':'大阪府','population':8779000,'subregions':[{'name':'大阪市','pop':2750000}]},
    ]
}
# 1段目を展開
df = pd.json_normalize(nested['data'], record_path='subregions', meta=['prefecture','population'])
print(df)
📤 実行例(実測) name pop prefecture population 0 23区 9700000 東京都 14086000 1 多摩 4200000 東京都 14086000 2 大阪市 2750000 大阪府 8779000

レシピ3: JSON Schema で検証

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
import jsonschema
schema = {
  "type": "object",
  "required": ["metadata","data"],
  "properties": {
    "metadata": {"type":"object", "required":["source","year"],
                 "properties":{"source":{"type":"string"},"year":{"type":"integer","minimum":2000}}},
    "data": {"type":"array",
             "items":{"type":"object","required":["prefecture","population"],
                      "properties":{"prefecture":{"type":"string"},
                                    "population":{"type":"integer","minimum":0},
                                    "aged_ratio":{"type":"number","minimum":0,"maximum":100}}}}
  }
}
jsonschema.validate(loaded, schema)
print('Schema OK')
📤 実行例(実測) Schema OK

レシピ4: jq 風クエリで深い JSON を探索

1
2
3
4
5
6
7
8
# pip install jmespath
import jmespath
# data 配列から population 1000万超のレコードを抽出
# JMESPath では英数字以外のキー名は二重引用符で囲む必要がある
big = jmespath.search(
    'data[?population > `10000000`].{"県": prefecture, "人口": population}', loaded)
print(big)
# → [{'県':'東京都','人口':14086000}, {'県':'神奈川県','人口':9230000}]
📤 実行例(実測) [{'県': '東京都', '人口': 14086000}]

レシピ5: JSON Lines で大規模ログを処理

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
import os
os.makedirs('outputs', exist_ok=True)  # 保存先のフォルダを作っておく

# 47県を 1 行 1 オブジェクトで保存
df23.to_json('outputs/ssdse_b_2023.ndjson', orient='records', lines=True, force_ascii=False)
# 読み込みもストリーミング可能
import pandas as pd
records = []
with open('outputs/ssdse_b_2023.ndjson',encoding='utf-8') as f:
    for line in f:
        records.append(json.loads(line))
print(len(records), records[0])
📤 実行例(実測) 47 {'code': 'R01000', 'prefecture': '北海道', 'population': 5092000, 'aged_pop': 1681000, 'aged_ratio': 33.01}

🚫 アンチパターン集

  1. 巨大 JSON を全体ロード: 1GB の JSON を json.load でメモリに展開して OOM。 → ijson でストリーミング、 または NDJSON 化。
  2. 金額を float で保存: 0.1 + 0.2 = 0.30000000000000004 問題。 → 整数 (銭単位) または文字列で。
  3. 循環参照: a={'x':1}; a['self']=a; json.dump(a) は無限再帰。 → 平坦化または ID 参照。
  4. datetime をそのまま dump: TypeError: Object of type datetime is not JSON serializable。 → ISO 8601 文字列に変換。
  5. キーに数値や非文字列: JSON のキーは必ず string。 dict のキーが int の場合は自動で str に変換されて齟齬。 → 明示的に str(key)。
  6. コメントや末尾カンマ: JSON5 にすればOKだが、 標準 JSON では parse エラー。
  7. 巨大整数を Number で送る: JavaScript の Number は 2^53-1 まで。 64-bit ID は string で。
  8. セキュリティ: 任意 JSON を eval: 古い JavaScript で eval(jsonStr) は危険。 必ず JSON.parse を使う。

❓ FAQ — 受講生からの頻出質問

Q1. JSON と YAML どっちを使う?
A. プログラム同士の通信は JSON、 人が編集する設定ファイルは YAML or TOML が定番。
Q2. JSON で日付はどう表現する?
A. JSON ネイティブの日付型はない。 ISO 8601 文字列 ("2023-12-31T23:59:59Z") が事実上の標準。 BSON / Protobuf は日付型をネイティブ対応。
Q3. JSON Schema を使うべき?
A. API の仕様書 (OpenAPI) と組み合わせると強力。 個人開発では省略してもよいが、 チーム開発では推奨。
Q4. ファイルサイズが大きい時の対策
A. (1) gzip 圧縮 (HTTP の Content-Encoding)、 (2) MessagePack / Protobuf へ変更、 (3) Parquet など列志向フォーマットを検討。
Q5. ストリーミングで読みたい
A. ijson ライブラリでイベント駆動パース。 もしくは JSON Lines (NDJSON) 形式にして 1 行ずつ処理。

合成データでネスト構造の JSON サイズを計算する。

Step 1: スキーマ

1 レコード: {id, name, age, addr:{city,zip}, tags:[3]} 推定サイズ ≈ 100 byte/レコード 記事数: 10,000

Step 2: 全体サイズ

JSON ≈ 100 × 10,000 = 1,000,000 byte ≈ 977 KB 配列要素 (tags) = 10,000 × 3 = 30,000 個 gzip 圧縮率 ≈ 0.30 → 圧縮後 ≈ 293 KB

🐍 Python で再現

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# ── この抜粋で使うログをここで作ります(架空)──
# アプリのログはこの教材に同梱していないので、NDJSON の読み書きを
# 試すための<架空の>ログレコードを作る。
import json

def stream_log_records():          # generator
    levels = ['INFO', 'ERROR', 'INFO', 'WARN', 'ERROR']
    for i, lv in enumerate(levels):
        yield {'ts': f'2024-05-01T10:0{i}:00', 'level': lv, 'msg': f'処理 {i}'}

# NDJSON 書き込み
with open('logs.ndjson','w',encoding='utf-8') as f:
    for record in stream_log_records():
        f.write(json.dumps(record, ensure_ascii=False) + '\n')

# NDJSON 読み込み (1行ずつ)
def read_ndjson(path):
    with open(path,encoding='utf-8') as f:
        for line in f:
            yield json.loads(line)

count = sum(1 for r in read_ndjson('logs.ndjson') if r.get('level')=='ERROR')
print(f'ERROR 件数 = {count}')

📤 実行結果

JSON: 977 KB gzip: 293 KB 配列要素: 30000

💬 手計算 (Step 2) と Python 出力が完全一致。

🐍 Python での扱い

SSDSE-B-2026 のような公的統計データを Python で扱う際の基本パターン:

📥 入力例(SSDSE-B-2026 全体:564 行 × 112 列 = 47 都道府県 × 2012〜2023 年) 年度 地域コード 都道府県 A1101(総人口) A1303(65歳以上人口) A4101(出生数) … 2023 R01000 北海道 5,092,000 1,681,000 24,430 … 2023 R13000 東京都 14,086,000 3,205,000 86,348 … 2023 R47000 沖縄県 1,468,000 350,000 12,549 … …(残り 112 列は住宅・家計・教育・医療など)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
import pandas as pd
import numpy as np

# データ読み込み
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
print(df.shape)
print(df.dtypes)
print(df.describe())

# 「JSON」の文脈で扱う場合の例:
# 分野: データエンジニアリング
# 関連手法は同カテゴリの他用語を参照してください。
📤 実行例(実測) (564, 112) SSDSE-B-2026 int64 Code object Prefecture object A1101 int64 A110101 int64 ... L322106 int64 L322107 int64 L322108 int64 L322109 int64 L322110 int64 Length: 112, dtype: object SSDSE-B-2026 A1101 ... L322109 L322110 count 564.000000 5.640000e+02 ... 564.000000 564.000000 mean 2017.500000 2.690688e+06 ... 26931.026596 59784.718085 std 3.455117 2.730951e+06 ... 4219.487086 8813.812956 min 2012.000000 5.370000e+05 ... 14661.000000 35658.000000 25% 2014.750000 1.082250e+06 ... 24200.750000 53794.500000 50% …(以下略)

具体的なコードは データエンジニアリング を参照してください。

📝 レポートでの報告

分析結果を報告するときに含めるべき情報:

✅ チェックリスト

⚠️ よくある落とし穴

❌ テスト時の未知カテゴリ
OneHotEncoder(handle_unknown="ignore") 等で対応。
❌ リーク防止
前処理は CV の各 fold 内で fit。 Pipeline を使う。
❌ 文字コード
日本語 CSV は utf-8 / cp932 を試す。

⚠️ JSON 取り扱いの罠

❌ 1. 整数のオーバーフロー
JavaScript の Number は 2^53 - 1 まで。 SSDSE-B の人口(数千万)は安全だが、 マイナンバーや 64bit ID は文字列で送る。
❌ 2. 浮動小数の精度
0.1 + 0.2 = 0.30000000000000004。 金額は文字列か固定小数(整数で銭単位)で表現。
❌ 3. 日付の表現が標準化されない
JSON 本体に日付型はない。 ISO 8601 文字列 (\"2023-12-31T23:59:59Z\") を慣習にする。
❌ 4. NaN / Infinity が JSON 標準にない
pandas の NaN を to_json すると null に化ける。 区別が必要なら欠損フラグ列を別に持つ。
❌ 5. UTF-8 エスケープと ensure_ascii
ensure_ascii=True だと日本語が \\u3042... になり読めない。 False を指定して UTF-8 をそのまま保持。

🎮 触って理解する — JSON ライブビューア

左のテキストを編集すると即座に JSON.parse による構文チェックが走り、正しければ右に色分けツリーが、間違っていればエラー位置と「JSON 特有の落とし穴」の原因推定が表示される。▾ をタップするとネスト階層を折りたためる。壊れた JSON のプリセットボタンで、末尾カンマ・シングルクォート・引用符なしキーなどの典型エラーを実際に体感してみよう。

✏️ JSON テキスト(編集可)
🌳 ツリー表示(型で色分け)
📊 値の型の内訳 — バーに触れる/指でなぞると該当ノードが黄色く強調
🔢 数値サマリ(リアルタイム更新)
リーフ値の数
キーの総数
最大ネスト深さ
UTF-8 バイト数

💡 直感 — JSON は「入れ子の辞書と配列」でデータを運ぶ

JSON の文法は驚くほど小さい。 {}(オブジェクト = キーと値の辞書)[](配列 = 順序付きリスト)の 2 つの容れ物に、文字列数値真偽値null の 4 種のスカラーを入れ子にするだけ。 CSV が「平坦な表」しか運べないのに対し、JSON は上のサンプルのように「metadata(辞書)+ data(レコードの配列)」という階層をそのまま 1 つのテキストで運べる。 ツリー表示の ▾ を折りたたんで全体の骨格だけを眺めると、「辞書と配列の入れ子」という構造が一目で掴める。

⚠️ よくある落とし穴 — 壊れた JSON ボタンで体感する

🚀 発展 — JSON Lines・API・pandas の json_normalize

JSON Lines(NDJSON)は「1 行 = 1 個の JSON」を改行で並べる形式で、全体を [...] で包まないため、巨大データでも 1 行ずつストリーミング処理でき、ログ収集や機械学習データセット(例: 大規模コーパス配布)の事実上の標準になっている。 API の世界では REST レスポンスの大半が JSON であり、e-Stat など公的統計 API も JSON を返す。 受け取ったネスト JSON を分析にかけるときは、上の「JSON→表」ボタンと同じことを pandas の pd.json_normalize(data, record_path="data", meta=...) が行う — ネストされたキーは metadata.source のようなドット記法の列名に展開され、DataFrame として CSV 的な平坦表に着地する。 「階層の JSON ↔ 平坦な表」を自在に往復できることが、構造化データを扱うデータエンジニアリングの基礎体力になる。

🗺 概念マップ — JSON の位置づけ

                           ┌─────────────────────────┐
                           │   データ交換フォーマット   │
                           └────────┬────────────────┘
                                    │
            ┌───────────────────────┼───────────────────────┐
            ▼                       ▼                       ▼
       ┌─────────┐             ┌─────────┐            ┌─────────┐
       │  CSV    │             │  JSON   │            │  XML    │
       │ (表形式) │             │ (階層)   │            │ (汎用)   │
       └─────────┘             └────┬────┘            └─────────┘
                                    │
            ┌───────────────────────┼───────────────────────┐
            ▼                       ▼                       ▼
       ┌─────────────┐        ┌─────────────┐        ┌──────────────┐
       │ JSON Schema │        │JSON Lines   │        │  JSON-LD     │
       │ (型検証)     │        │(1行1オブジェクト)│        │ (Linked Data)│
       └─────────────┘        └─────────────┘        └──────────────┘
                                    │
                ┌───────────────────┼─────────────────┐
                ▼                   ▼                 ▼
           ┌─────────┐         ┌─────────┐       ┌────────┐
           │ REST API│         │ NoSQL   │       │設定ファイル│
           │(e-Stat等)│         │(MongoDB)│       │(package.json)│
           └─────────┘         └─────────┘       └────────┘

   バイナリ系派生:
     - MessagePack (JSON 互換バイナリ)
     - BSON (MongoDB 内部)
     - Protobuf, Avro (スキーマ駆動)
  
json 絶対に eval() しない サイズ制限 JSON Hijacking Prototype Pollution 個人情報 JSON Schema 検証

🔗 隣接手法への橋渡し

JSON (JavaScript Object Notation) は Web API ・ 設定ファイル ・ NoSQL DB のデファクトデータ交換形式。 単独で意味を持たず、 解析ライブラリ・スキーマ検証・データベースと一体で使う。

JSON は階層構造を表現できる点が CSV より優位だが、 大量データには非効率 (テキスト + キー名重複)。 100MB を超えるなら Parquet (列指向 + 圧縮) を検討。

🌳 手法選択フロー

データ形式を、 構造・サイズ・用途で 3 段階で判定する。

  1. データは表形式か階層構造か? 表形式 → CSV / TSV (シンプル)、 階層構造 → JSON (Web API) / YAML (設定) / XML (古い系)
  2. データサイズは? 1MB 未満 → JSON で十分、 1-100MB → JSON で OK だが pandas で扱う、 100MB 以上 → Parquet / Arrow / HDF5 (バイナリ列指向で 10 倍速い)
  3. 利用目的は? Web API → JSON (デファクト)、 機械学習バッチ → Parquet (列指向 + 型付き)、 人間が手で編集 → YAML (コメント可能)、 高速 IPC → Protocol Buffers

初心者は import json; data = json.loads(text) で Python の dict/list に変換できる。 ネスト構造を表形式にしたいときは pd.json_normalize(data) が便利。

🧩 JSON 深掘り ── 同じ数値でも「書き方」でサイズが 2 倍変わる

JSON(JavaScript Object Notation=データ交換のためのテキスト形式)は「値ひとつひとつに名札(キー)を貼って運ぶ」自己記述的なフォーマット。このページの他セクションが Schema・JSON Lines・API 取得を扱ったので、ここでは「表データを JSON にすると、書き方(orient)次第で大きさが激変する」という別角度に絞る。題材は SSDSE-B-2026 の 2023 年・47 都道府県・112 列(実測データ)。姉妹ページの CSV(ファイルサイズの見積り)や API(文字列型の検算)とは重ならない、「構造の冗長性」という JSON 固有の論点を扱う。

🎨 直感

CSV は「見出し(列名)を先頭で 1 回だけ書き、あとは値だけ並べる」。対して JSON の records 形式は1 行ごとに列名という名札を貼り直す——付箋を全セルに貼るイメージ。だから階層構造や単一レコードには強いが、同じ列が何十行も続く「表」を運ぶと名札の重複でかさむ。逆に、ネストした JSON を pd.json_normalize() に通すと、階層のキーが meta.yearpref.code のようにドットで平坦化され、tidy な表(DataFrame / 整然データ)に落ちる。「名札を貼る/剥がす」の往復が JSON 運用の勘所。

⚠️ 落とし穴(重要)

🚀 発展

下は「県数を増やすと CSV・JSON(split)・JSON(records) のバイト数がどう伸びるか」を、実測アンカー(1 県と 47 県)からの線形補間で見るミニ実験。バーをドラッグ(スマホは指でなぞる)か「🎲」で県数が変わる。47 県ちょうどが上記①の実測値。(補間途中の値は概算。両端=1 県・47 県のみ実測。)

県数 47 / 47 (records は CSV の 2.49 倍)
CSV
JSON(split)
JSON(records)

教訓:表データを JSON で渡すなら orient="split"(列名を 1 回だけ持つ)や CSV/Parquet を選べば、records の名札重複を避けられる。

🔗 関連ページ