JSONデータをPandasでDataFrameに変換:json_normalizeの使い方とサンプルコード

2024-04-02

pandas.json_normalizeは、複雑なJSONデータを平坦なDataFrameに変換する強力なツールです。JSONデータは、階層構造やリスト、辞書など、さまざまな形式で表現されます。json_normalizeは、これらの複雑な構造を扱いやすくするために、データを正規化(flatten)します。

使い方

json_normalizeの基本的な使い方は以下の通りです。

import pandas as pd

# JSONデータ
data = [
    {
        "name": "John Doe",
        "age": 30,
        "address": {
            "street": "123 Main Street",
            "city": "New York",
            "state": "NY",
            "zip": "10001"
        },
        "phone_numbers": [
            {
                "type": "home",
                "number": "(123) 456-7890"
            },
            {
                "type": "mobile",
                "number": "(987) 654-3210"
            }
        ]
    },
    {
        "name": "Jane Doe",
        "age": 25,
        "address": {
            "street": "456 Elm Street",
            "city": "Los Angeles",
            "state": "CA",
            "zip": "90001"
        },
        "phone_numbers": [
            {
                "type": "home",
                "number": "(456) 123-4567"
            }
        ]
    }
]

# JSONデータをDataFrameに変換
df = pd.json_normalize(data)

# 結果
print(df)

#   name  age                                     address  ... phone_numbers_type_home phone_numbers_number_home phone_numbers_type_mobile phone_numbers_number_mobile
# 0  John Doe   30  {'street': '123 Main Street', 'city': ...        home          (123) 456-7890                     mobile          (987) 654-3210
# 1  Jane Doe   25  {'street': '456 Elm Street', 'city': ...        home          (456) 123-4567                            NaN

この例では、dataというリストに格納されたJSONデータをjson_normalizeで処理し、dfというDataFrameに変換しています。

主な引数

  • data: 変換したいJSONデータ。dict、list、str型を受け取ります。
  • record_path: リスト型で、JSONデータの各レコードを抽出するためのパスを指定します。
  • meta: リスト型で、JSONデータのメタデータを抽出するためのパスを指定します。
  • errors: エラー処理方法を指定します。'raise'(デフォルト)はエラー発生時に例外を発生させ、'ignore'はエラーを無視します。
  • sep: 複数のキーを結合する際の区切り文字を指定します。デフォルトは.です。
  • max_level: JSONデータの最大階層数を指定します。

詳細

json_normalizeには、上記以外にもさまざまな引数があります。詳細は以下のドキュメントを参照してください。

応用例

json_normalizeは、以下のようなさまざまな場面で役立ちます。

  • APIから取得したJSONデータを分析する
  • データベースから抽出


Pandasのjson_normalizeサンプルコード

import pandas as pd

# JSONデータ
data = [
    {"name": "John Doe", "age": 30},
    {"name": "Jane Doe", "age": 25},
]

# DataFrameに変換
df = pd.json_normalize(data)

# 結果
print(df)

#   name  age
# 0  John Doe   30
# 1  Jane Doe   25

複数階層のJSONデータの正規化

import pandas as pd

# JSONデータ
data = [
    {
        "name": "John Doe",
        "address": {
            "street": "123 Main Street",
            "city": "New York",
            "state": "NY",
            "zip": "10001",
        },
    },
    {
        "name": "Jane Doe",
        "address": {
            "street": "456 Elm Street",
            "city": "Los Angeles",
            "state": "CA",
            "zip": "90001",
        },
    },
]

# record_pathで階層を指定
df = pd.json_normalize(data, record_path="address")

# 結果
print(df)

#                                 street          city state  zip
# 0                        123 Main Street  New York    NY  10001
# 1                        456 Elm Street  Los Angeles    CA  90001

リスト型データの展開

import pandas as pd

# JSONデータ
data = [
    {
        "name": "John Doe",
        "phone_numbers": [
            {"type": "home", "number": "(123) 456-7890"},
            {"type": "mobile", "number": "(987) 654-3210"},
        ],
    },
    {
        "name": "Jane Doe",
        "phone_numbers": [{"type": "home", "number": "(456) 123-4567"}],
    },
]

# phone_numbersを列に展開
df = pd.json_normalize(data, record_path="phone_numbers")

# 結果
print(df)

#   name  type  number
# 0  John Doe  home  (123) 456-7890
# 1  John Doe  mobile  (987) 654-3210
# 2  Jane Doe  home  (456) 123-4567

メタデータの抽出

import pandas as pd

# JSONデータ
data = [
    {
        "name": "John Doe",
        "age": 30,
        "metadata": {"created_at": "2023-01-01"},
    },
    {
        "name": "Jane Doe",
        "age": 25,
        "metadata": {"created_at": "2023-01-02"},
    },
]

# metaでメタデータを抽出
df = pd.json_normalize(data, meta="metadata")

# 結果
print(df)

#   name  age  created_at
# 0  John Doe   30  2023-01-01
# 1  Jane Doe   25  2023-01-02

エラー処理

import pandas as pd

# JSONデータ
data = [
    {"name": "John Doe", "age": 30},
    {"name": "Jane Doe"},  # "age"キーがない
]

# errors='ignore'でエラーを無視
df = pd.json_normalize(data, errors="ignore")

# 結果
print(df)

#   name  age
# 0  John Doe   30
# 1  Jane Doe  NaN

その他のオプション

  • sep: 複数のキーを結合する際の区切り文字
  • max_level: JSONデータの最大階層数

詳細は Pandas ドキュメントの json_normalize を参照してください。



PandasでJSONデータを扱うその他の方法

DataFrame.from_dict

単純な構造のJSONデータであれば、DataFrame.from_dictを使ってDataFrameに変換できます。

import pandas as pd

# JSONデータ
data = {"name": ["John Doe", "Jane Doe"], "age": [30, 25]}

# DataFrameに変換
df = pd.DataFrame.from_dict(data)

# 結果
print(df)

#   name  age
# 0  John Doe   30
# 1  Jane Doe   25

DataFrame.from_records

リスト型で格納されたJSONデータを、DataFrame.from_recordsを使ってDataFrameに変換できます。

import pandas as pd

# JSONデータ
data = [
    {"name": "John Doe", "age": 30},
    {"name": "Jane Doe", "age": 25},
]

# DataFrameに変換
df = pd.DataFrame.from_records(data)

# 結果
print(df)

#   name  age
# 0  John Doe   30
# 1  Jane Doe   25

json.loadsを使ってJSONデータをPythonオブジェクトに変換し、それをPandasのDataFrameに変換する方法もあります。

import pandas as pd
import json

# JSONデータ
data = """
[
    {"name": "John Doe", "age": 30},
    {"name": "Jane Doe", "age": 25},
]
"""

# JSONデータをPythonオブジェクトに変換
json_data = json.loads(data)

# DataFrameに変換
df = pd.DataFrame(json_data)

# 結果
print(df)

#   name  age
# 0  John Doe   30
# 1  Jane Doe   25

ライブラリ

  • jsonpath-rw: JSONパスの抽出に特化したライブラリ
  • pydantic: JSONデータのバリデーションと型変換に特化したライブラリ

これらのライブラリを使うことで、より複雑なJSONデータ処理を行うことができます。

JSONデータの構造や処理内容によって、適切な方法は異なります。

  • 構造が単純な場合は DataFrame.from_dictDataFrame.from_records
  • 複雑な構造の場合は json_normalize
  • 特殊な処理が必要な場合は ライブラリの利用

それぞれの特徴を理解して、状況に応じて使い分けてください。




Pandasで月末から15日と月末を表す:SemiMonthEnd.freqstr徹底解説

SemiMonthEndは、月末から15日と月末を表すData Offsetです。例えば、2024年4月15日は月末から15日、2024年4月30日は月末に当たります。SemiMonthEnd. freqstrは、SemiMonthEndオフセットの文字列表現を取得するための属性です。これは、データフレームやインデックスの周波数を表示したり、日付範囲を生成したりする際に役立ちます。



Pandas WeekOfMonth.is_quarter_start 属性のユースケース

この解説は、Python ライブラリ Pandas の Data Offsets 機能と、WeekOfMonth オブジェクトの is_quarter_start 属性について、プログラミング初心者にも分かりやすく説明することを目的としています。


【完全ガイド】pandasで時系列データのオフセット設定:Tick.n、DateOffset、その他の方法

pandas. tseries. offsets. Tick. n は、時系列データのオフセットを設定するために使用されるクラスです。これは、pandas ライブラリの時系列モジュールの一部であり、データフレームのインデックスを調整し、異なる時間間隔のデータを比較できるようにします。


Pandas YearEnd オフセット:DatetimeIndex/Series/Resampling との連携

YearEnd オフセットは、年末 に日付を進めるオフセットです。例えば、2023-03-08 に YearEnd オフセットを適用すると、2023-12-31 になります。YearEnd オフセットは、以下のパラメータを受け取ります。n: オフセットの回数 (デフォルトは 1)


Pandas Data Offsets:pandas.tseries.offsets.SemiMonthEnd.n 完全ガイド

pandas. tseries. offsets. SemiMonthEnd. n は、pandas データフレームの日付オフセットを表すオブジェクトです。これは、月末から数えて n 番目の半月を表します。主な用途:特定の半月(月初から数えて 15 日目または月末)に関連するデータ分析



Pandas Data Offsets: MonthBegin.is_quarter_end を活用した四半期分析

pandas. tseries. offsets. MonthBegin. is_quarter_end は、月初めの日付が四半期末かどうかを判定する関数です。四半期とは、1年を4等分した期間です。(1月~3月、4月~6月、7月~9月、10月~12月)


Pandasで差をつけろ: Styler.applymap を使った高度なスタイル設定

pandas. io. formats. style. Styler. applymapは、PandasのDataFrameのセルに個別にスタイルを適用するための強力なツールです。セル値に基づいて、色、フォント、背景色などのスタイルを個別に設定できます。


会計年度に基づく四半期オフセット:pandas.tseries.offsets.FY5253Quarter

pandas. tseries. offsets. FY5253Quarter. qtr_with_extra_week は、会計年度に基づく四半期オフセットを表すクラスです。このオフセットは、13週からなる4つの四半期で構成される会計年度に使用されます。


Pandas WeekOfMonth.is_quarter_start 属性のユースケース

この解説は、Python ライブラリ Pandas の Data Offsets 機能と、WeekOfMonth オブジェクトの is_quarter_start 属性について、プログラミング初心者にも分かりやすく説明することを目的としています。


Pandas Expanding Window と statsmodels

Expanding Window と組み合わせて使用する aggregate 関数は、集計したい関数を指定することで、Window 内のデータを集計することができます。例:上記の例では、aggregate 関数に 'sum' を指定することで、Window 内のデータの累計値を計算しています。