Денормализовать объект json на плоские объекты - PullRequest
1 голос
/ 22 июня 2019

У меня есть объект 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 и повторить информацию о родительском объекте.

любая помощь в этом отношении очень ценится.

Ответы [ 2 ]

2 голосов
/ 22 июня 2019

Вам нужно поведение json_normalize, но с пользовательским поворотом. Поэтому используйте json_normalize или аналогичный для части данных, а затем объедините его с оставшейся частью данных.

Приведенный ниже код предпочитает «или подобный» маршрут, достигая глубины в базе кодов панд , чтобы получить вспомогательную функцию nested_to_record, которая сглаживает словари. Он используется для создания отдельных строк, которые объединяют базовые данные (ключи / значения, общие для всех свойств) со сглаженными данными, характерными для каждой записи реквизита. Есть закомментированная строка, которая делает эквивалентную вещь без 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)

В результате:

output data frame

1 голос
/ 22 июня 2019

, пожалуйста, попробуйте это:

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" (который является общей частью для использования во всех объектах результата),

затем мы перебираем реквизиты и создаем новые объекты, содержащие базовый объект, а затем заполняем «props.key» для каждого ключа в каждом реквизите.

...