目的
複雑なjsonをパースし要素ごとのキーをアンダーバーでつなぎ、要素の値と分けて配列で格納することです。
データ分析でjsonをそのまま分析するのではなく一旦非構造化データにするためにこのような処理が必要でした。
参考データ
{"meta":"fluits","apple": {"fuji ringo" : 120, "toki ringo" : 250, "sekai ichi" : 250}, "grape" : {"fujiminori" : 650, "shigyoku" : 780, "kyohou" : {"big kyohou" : 780, "smale kyohou":570}}, "date":"2022-08-05"}
コード
jsonの階層をfor分で定義することが不可能なので、再帰アルゴリズムを使用します。
これによってコードがシンプルに書けます。
json_dict = json.loads('{"meta":"fluits","apple": {"fuji ringo" : 120, "toki ringo" : 250, "sekai ichi" : 250}, "grape" : {"fujiminori" : 650, "shigyoku" : 780, "kyohou" : {"big kyohou" : 780, "smale kyohou":570}}, "date":"2022-08-05"}')
arr = []
def parse_json(json_dict, prefix):
print(json_dict.keys())
# dictではなく、キーとバリューだけの場合
for key in json_dict.keys():
element = json_dict[key]
if type(element) != dict:
if len(prefix) == 0:
arr.append([key, element])
else:
arr.append([prefix + "_" + key, element])
# 上記以外の場合
for key in json_dict.keys():
element = json_dict[key]
if type(element) == dict:
if len(prefix) == 0:
yield from parse_json(element, str(key))
else:
yield from parse_json(element, prefix + "_" + str(key))
呼び出し方
ジェネレーターを使用しているので以下のように書き、呼び出します。
for x in parse_json(json_dict, ""):
pass
出力
[['meta', 'fluits'],
['date', '2022-08-05'],
['apple_fuji ringo', 120],
['apple_toki ringo', 250],
['apple_sekai ichi', 250],
['grape_fujiminori', 650],
['grape_shigyoku', 780],
['grape_kyohou_big kyohou', 780],
['grape_kyohou_smale kyohou', 570]]