【问题标题】:De-normalize json object into flat objects将 json 对象反规范化为平面对象
【发布时间】:2019-06-22 15:15:15
【问题描述】:

我有一个类似的 json 对象

 {
        "id": 3590403096656,
        "title": "Romania Special Zip Hoodie Blue - Version 02 A5",
        "tags": [
            "1ST THE WORLD FOR YOU <3",
            "apparel",
        ],
        "props": [
            {
                "id": 28310659235920,
                "title": "S / romainia All Over Print Full Zip Hoodie for Men (Model H14)",
                "position": 1,
                "product_id": 3590403096656,
                "created_at": "2019-05-22T00:46:19+07:00",
                "updated_at": "2019-05-22T01:03:29+07:00"
            },
            {
                "id": 444444444444,
                "title": "number 2",
                "position": 1,
                "product_id": 3590403096656,
                "created_at": "2019-05-22T00:46:19+07:00",
                "updated_at": "2019-05-22T01:03:29+07:00"
            }
        ]
}

我想把它弄平,所以想要的输出看起来像

{"id": 3590403096656,"title": "Romania Special Zip Hoodie Blue - Version 02 A5","tags": ["1ST THE WORLD FOR YOU <3","apparel"],"props.id": 28310659235920,"props.title": "S / romainia All Over Print Full Zip Hoodie for Men (Model H14)","props.position": 1,"props.product_id": 3590403096656,"props.created_at": "2019-05-22T00:46:19+07:00",       "props.updated_at": "2019-05-22T01:03:29+07:00"}
{"id": 3590403096656,"title": "Romania Special Zip Hoodie Blue - Version 02 A5","tags": ["1ST THE WORLD FOR YOU <3","apparel"],"props.id": 444444444444,"props.title": "number 2","props.position": 1,"props.product_id": 3590403096656,"props.created_at": "2019-05-22T00:46:19+07:00","props.updated_at": "2019-05-22T01:03:29+07:00"}

到目前为止我已经尝试过:

from pandas.io.json import json_normalize
json_normalize(sample_object)

其中sample_object 包含json 对象,我正在循环通过这些对象的大文件,我想以所需的格式展平。

json_normalize 没有给我想要的输出,我想保持标签不变,但将props 展平并重复父对象信息。

【问题讨论】:

    标签: python json pandas ndjson


    【解决方案1】:

    您想要一些 json_normalize 行为,但需要自定义扭曲。因此,对部分数据使用json_normalize 或类似名称,然后将其与其余数据结合起来。

    下面的代码更喜欢“或类似”的路线,深入into the pandas codebase 以获取nested_to_record 帮助函数,该函数将字典扁平化。它用于创建单独的行,将基础数据(所有属性中通用的键/值)与特定于每个 props 条目的展平数据结合起来。有一条注释掉的行在没有nested_to_record 的情况下执行相同的操作,但它有点不雅地扁平化为DataFrame,然后导出为dict

    from collections import OrderedDict
    import json
    import pandas as pd
    from pandas.io.json.normalize import nested_to_record
    
    data = json.loads(rawjson)
    props = data.pop('props')
    rows = []
    for prop in props:
        rowdict = OrderedDict(data)
        flattened_prop = nested_to_record({'props': prop})
        # flatteded_prop = json_normalize({'props': prop}).to_dict(orient='records')[0]
        rowdict.update(flattened_prop)
        rows.append(rowdict)
    
    df = pd.DataFrame(rows)
    

    导致:

    【讨论】:

    • 感谢您的回答和详细解释,如果我有一个数组中的这些对象的集合并且所有这些对象都有props 键怎么办?
    【解决方案2】:

    请试试这个:

    import copy
    
    obj =  {
            "id": 3590403096656,
            "title": "Romania Special Zip Hoodie Blue - Version 02 A5",
            "tags": [
                "1ST THE WORLD FOR YOU <3",
                "apparel",
            ],
            "props": [
                {
                    "id": 28310659235920,
                    "title": "S / romainia All Over Print Full Zip Hoodie for Men (Model H14)",
                    "position": 1,
                    "product_id": 3590403096656,
                    "created_at": "2019-05-22T00:46:19+07:00",
                    "updated_at": "2019-05-22T01:03:29+07:00"
                },
                {
                    "id": 444444444444,
                    "title": "number 2",
                    "position": 1,
                    "product_id": 3590403096656,
                    "created_at": "2019-05-22T00:46:19+07:00",
                    "updated_at": "2019-05-22T01:03:29+07:00"
                }
            ]
    }
    
    props = obj.pop("props")
    
    for p in props:
        res = copy.deepcopy(obj)
        for k in p:
            res["props."+k] = p[k]
        print(res)
    

    基本上它使用pop("props") 来获取没有"props" 的obj(这是所有结果对象中通用的部分),

    然后我们遍历道具,并创建包含基础对象的新对象,然后为每个道具中的每个键填充“props.key”。

    【讨论】:

    • 仅在 Python 3.5 及更高版本中。
    • @connectyourcharger 没错,我将使用 deepcopy 代替 **
    • 你走了,抱歉耽搁了你的回答让我走上了正确的道路,再次感谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-16
    • 1970-01-01
    相关资源
    最近更新 更多