0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

pandas.json_normalize の逆

Last updated at Posted at 2021-12-03

ネストされた 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}}]
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?