🆗

【Python・PySparkで学ぶ!】JSONファイルをデータフレーム化(ネストなし)

2025/03/09に公開

はじめに、APIを叩いてみる。

郵便番号検索API
import requests
res = requests.get("https://zipcloud.ibsnet.co.jp/api/search?zipcode=1000001")
print(f"リクエストステータス : {res.status_code}")
print("------------")
print(res.text)
print("------------")
res_json = res.json()
レスポンス結果
リクエストステータス : 200
------------
{
	"message": null,
	"results": [
		{
			"address1": "東京都",
			"address2": "千代田区",
			"address3": "千代田",
			"kana1": "トウキョウト",
			"kana2": "チヨダク",
			"kana3": "チヨダ",
			"prefcode": "13",
			"zipcode": "1000001"
		}
	],
	"status": 200
}
------------

上記の結果を使用し、PySparkのデータフレームを作成します。

◾️ アウトプットイメージ

zip_code prefecture city
1000001 東京都 千代田区

◾️ コーディング

Json形式のPySparkデータフレーム化
import requests
from pyspark.sql import SparkSession
from pyspark.sql.types import StructType, StructField, StringType

# Sparkセッションの作成
spark = SparkSession.builder.appName("ZipcodeAPI").getOrCreate()

# スキーマの定義
schema = StructType([
    StructField("zip_code", StringType(), True),
    StructField("prefecture", StringType(), True),
    StructField("city", StringType(), True)
])

# 「zipコード(文字列)を渡して、データフレームが戻る」関数
def get_address_spark_df(zipcode: str):
    
    url = f"https://zipcloud.ibsnet.co.jp/api/search?zipcode={zipcode}"
    res = requests.get(url, timeout=5)
    
    print(f"リクエストステータス : {res.status_code}")
    print("------------")
    print(res.text)
    print("------------")


    if res.status_code != 200:
        return spark.createDataFrame([], schema)

    res_json = res.json()
    
    # API の `status` が 200 ならデータを取得
    if res_json.get("status") == 200 and res_json.get("results"):
        data = res_json["results"][0]
        row = (
            data.get("zipcode", "不明"),
            data.get("address1", "不明"),
            data.get("address2", "不明")
        )
        df = spark.createDataFrame([row], schema)
    else:
        df = spark.createDataFrame([], schema)
    
    return df

# 例: 郵便番号 "1000001" で検索
spark_df = get_address_spark_df("1000001")
spark_df.show(50, truncate=False)
zip_code prefecture city
1000001 東京都 千代田区

気を付けるべきポイント

◾️ 課題・解決策の1対1

  1. APIレスポンスのネスト構成が不明
    • 課題:レスポンスされたJsonファイルの形式が不明で、意図しないスキーマのデータフレームが作成される可能性がある。
    • 解決策:print(res.text)を事前に実行し、Jsonファイルのネスト構成を確認する。
解決策①レスポンス確認
print(res.text)
  1. APIのレスポンスに想定外のデータ型が含まれる可能性
    • 課題: results 内の address1, address2, zipcode などのデータが None や ""(空文字)の場合、エラーが発生する可能性がある。
    • 解決策: .get("キー", "デフォルト値") を使って、None にならないようにデフォルト値を設定する。
解決策②デフォルト値を設定
data.get("zipcode", "不明")
  1. APIのレスポンス速度が遅いと処理が止まる
    • 課題: ネットワーク遅延やサーバー負荷によって requests.get() がタイムアウトすることがある。
    • 解決策: timeout を設定し、リクエストが長時間停止しないようにする。
解決策③タイムアウト設定
res = requests.get(url, timeout=5)  # 5秒でタイムアウト
  1. PySpark の show() でデータが見切れる
    • 課題: spark_df.show() では、デフォルトで最大 20 行しか表示されず、カラムも省略される可能性がある。
    • 解決策: .show(n, truncate=False) を使い、全データを見やすく表示する。
解決策④データを見やすく表示
spark_df.show(50, truncate=False)  # 50行表示 & 切り詰めなし

Discussion