#python #arrays #json
#python #json #панды #ndjson
Вопрос:
У меня есть объект 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
и повторить информацию о родительском объекте.
Ответ №1:
Вам нужно какое json_normalize
-то поведение, но с особым уклоном. Поэтому используйте json_normalize
или аналогичный для части данных, затем объедините его с остальными данными.
Приведенный ниже код предпочитает «или аналогичный» маршрут, проникающий глубоко в кодовую базу pandas, чтобы получить nested_to_record
вспомогательную функцию, которая выравнивает словари. Он используется для создания отдельных строк, которые объединяют базовые данные (ключи / значения, общие для всех свойств) со сглаженными данными, специфичными для каждой записи реквизитов. Существует закомментированная строка, которая делает то же самое без nested_to_record
, но она несколько неэлегантно сглаживается в a DataFrame
, а затем экспортируется в a 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)
В результате:
Комментарии:
1. Спасибо за ваш ответ и подробное объяснение, еще одна вещь: что, если у меня есть коллекция таких объектов в массиве, и все они имеют
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"
(который является общей частью для использования во всех результирующих объектах),
затем мы перебираем props и создаем новые объекты, содержащие базовый объект, а затем заполняем «props.key» для каждого ключа в каждом реквизите.
Комментарии:
1. Только в Python 3.5 и выше.
2. @connectyourcharger это правильно, я буду использовать deepcopy вместо
**
3. вот так, извините за задержку, ваш ответ наставил меня на правильный путь, еще раз спасибо