首页 > 解决方案 > 如何在序列化为熊猫数据框时展平嵌套数据类?

问题描述

我有包含其他数据类作为其字段的数据类:

@dataclass
class Bar:
    abc: int
    bed: int
    asd: int


@dataclass
class Foo:
    xy: int
    yz: Bar

然后我尝试通过 pandas 将其序列化为 csv,如下所示:

dataset = [Foo(xy=1, yz=Bar(abc=1, bed=2, asd=3))]
pd_dataset = pandas.DataFrame(vars(row) for row in dataset)
pd_dataset.to_csv('dataset_example.csv', index=False)

但我得到的结果与我想要达到的结果有点不同。准确地说,我现在得到:

xy,yz
1,"Bar(abc=1, bed=2, asd=3)"

而且我要:

xy,yz_abc,yz_bed,yz_asd
1,1,2,3

你能帮我把它弄好吗?我尝试编写自己的序列化函数并执行以下操作: pandas.DataFrame(asdict(row, dict_factory=row_to_dict) for row in dataset) 但我不知道如何正确编写它。

标签: pythonpandaspython-dataclasses

解决方案


无需像此答案那样使用外部库,Pandas 以以下形式为您提供所需的一切pd.json_normalize

>>> import pandas as pd
... from dataclasses import asdict, dataclass
... 
... @dataclass
... class Bar:
...     abc: int
...     bed: int
...     asd: int
... 
... @dataclass
... class Foo:
...     xy: int
...     yz: Bar
... 
... dataset = [
...     Foo(xy=1, yz=Bar(abc=1, bed=2, asd=3)),
...     Foo(xy=10, yz=Bar(abc=10, bed=20, asd=30)),
... ]

>>> dataset
[Foo(xy=1, yz=Bar(abc=1, bed=2, asd=3)),
 Foo(xy=10, yz=Bar(abc=10, bed=20, asd=30))]

>>> df = pd.json_normalize(asdict(obj) for obj in dataset)
>>> df
   xy  yz.abc  yz.bed  yz.asd
0   1       1       2       3
1  10      10      20      30

>>> print(df.to_csv(index=False))
xy,yz.abc,yz.bed,yz.asd
1,1,2,3
10,10,20,30

我个人更喜欢上面的默认"."分隔符,但如果你对下划线有强烈的感觉,Pandas 也能满足你:

>>> pd.json_normalize((asdict(obj) for obj in dataset), sep="_")
   xy  yz_abc  yz_bed  yz_asd
0   1       1       2       3
1  10      10      20      30

推荐阅读