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