Sparkはさまざまなフォーマットのデータに対応しており、jsonデータも勿論readし、Databframeにすることができます。
{"a": 123,"b":"hello"},
{"a": 789,"b":"world"}
こんなjsonファイルがあったとして、こんな感じで読める。
df_from_json = (
spark
.read
.format("json")
.load("<file_name>.json")
)
値の中身にjsonがある場合
ここまでは「そりゃそうじゃん」って内容なのですが、じゃあ、カラム内の値がjsonだとしたら?
+---+------------------------------+
|no |value |
+---+------------------------------+
|1 |{"year": 2021,"rank":"junior"}|
|2 |{"year": 2022,"rank":"senior"}|
+---+------------------------------+
get_json_object
sparkは優秀なので、おあつらえむきなfunctionがあります。
こんな感じで書けます。
from pyspark.sql.functions import get_json_object,col
df_get_json = (
df_include_json
.withColumn("year", get_json_object(col("value"), "$.year").cast("string"))
.withColumn("rank", get_json_object(col("value"), "$.rank").cast("string"))
)
df_get_json.show()
>>>
+---+------------------------------+----+------+
|no |value |year|rank |
+---+------------------------------+----+------+
|1 |{"year": 2021,"rank":"junior"}|2021|junior|
|2 |{"year": 2022,"rank":"senior"}|2022|senior|
+---+------------------------------+----+------+
もちろん、select文を使うことで、value列を消して、見たい値だけ残すってことも可能です。
from pyspark.sql.functions import get_json_object,col
df_get_json = (
df_include_json
.withColumn("year", get_json_object(col("value"), "$.year").cast("string"))
.withColumn("rank", get_json_object(col("value"), "$.rank").cast("string"))
.select(
"no",
"year",
"rank"
)
)
df_get_json.show()
>>>
+---+----+------+
|no |year|rank |
+---+----+------+
|1 |2021|junior|
|2 |2022|senior|
+---+----+------+
これで美しくなりましたね。
どんなときに使う?
APIのGetメソッドを使って返ってきたレスポンス(json)は、とあるvalueの中身がまたjsonで…など、多階層にネストされていることもしばしば。
そんなときも根気よく掘って値を表示していきたい、っていうときに使えそうですね。
久しぶりにQiitaを書きました。
今後ともよろしくお願いします。
このシリーズの目的
クラウドストレージに蓄積された生データ(CSV,JSON等)を加工するのに必要なPysparkの知識を溜めていく、まさにPysparkに関するトリビアのDalta Lakeを目指しています。
Pysparkに関する記事はまだ海外のものが多く、このシリーズが私のような国内の駆け出しデータエンジニアの一助になることを願っています。