ネストされた dict の list をいい感じにフラットにしてくれる pandas.json_normalize
っていうのがあるんだけど、
https://pandas.pydata.org/pandas-docs/version/1.2.0/reference/api/pandas.json_normalize.html
元に戻す方法がないので書いた。
ちなみに数値はだいたい float64 になっちゃうので基本元の型には戻せないです。
import functools
import pandas as pd
def denormalize_json(df, sep="."):
def _denormalize_series(sr):
result = dict()
def _default_dict(acc, x):
if x not in acc:
acc[x] = dict()
return acc[x]
for k, v in sr.items():
p = k.split(sep)
d = functools.reduce(_default_dict, p[:-1], result)
if not pd.isna(v):
d[p[-1]] = v
return result
return [ _denormalize_series(sr) for _, sr in df.iterrows() ]
In [2]: l_nested = [{'name': 'Alice', 'age': 25, 'id': {'x': 2, 'y': 8}},
...: {'name': 'Bob', 'id': {'x': 10, 'y': 4}}]
...: l_nested
Out[2]:
[{'name': 'Alice', 'age': 25, 'id': {'x': 2, 'y': 8}},
{'name': 'Bob', 'id': {'x': 10, 'y': 4}}]
In [3]: pd.json_normalize(l_nested)
Out[3]:
name age id.x id.y
0 Alice 25.0 2 8
1 Bob NaN 10 4
In [4]: denormalize_json(pd.json_normalize(l_nested))
Out[4]:
[{'name': 'Alice', 'age': 25.0, 'id': {'x': 2, 'y': 8}},
{'name': 'Bob', 'id': {'x': 10, 'y': 4}}]