сгладить двояко вложенный словарь внутри списка с помощью json_normalize
response[0]={'@type': 'g:Vertex',
'@value': {'id': 'account-2199023262994',
'label': 'Account',
'properties': {'account_number': [{'@type': 'g:VertexProperty',
'@value': {'id': {'@type': 'g:Int32',
'@value': 544016139},
'value': '0002-1990-2326-2994',
'label': 'account_number'}}],
'last_name': [{'@type': 'g:VertexProperty',
'@value': {'id': {'@type': 'g:Int32',
'@value': -1616372909},
'value': 'Law-Yone',
'label': 'last_name'}}],
'first_name': [{'@type': 'g:VertexProperty',
'@value': {'id': {'@type': 'g:Int32',
'@value': -451458550},
'value': 'Eric',
'label': 'first_name'}}]}}}
У меня есть вложенный словарь в списке, который является частью другого вложенного словаря. Весь приведенный выше фрагмент кода сам по себе является элементом списка
Я попытался сгладить это, используя:
pd.json_normalize(response, meta = ['@type', ['@value', 'id'], ['@value', 'label'], ['@value', 'properties']])
Планирую также сгладить внутренние списки словарей.
Может кто-нибудь помочь мне здесь? Нужно ли мне перебирать фрейм данных или есть какие-то методы, доступные напрямую?
1 ответ
Вы можете использовать функцию рекурсивного генератора, чтобы получить полный сглаженный результат, строка за строкой, а затем использовать
collections.defaultdict
для группировки строк по идентификатору учетной записи. Оттуда вы можете взять желаемые ключи, чтобы построить свой финальный
pd.DataFrame
:
import pandas as pd, collections
data = {'@type': 'g:Vertex', '@value': {'id': 'account-2199023262994', 'label': 'Account', 'properties': {'account_number': [{'@type': 'g:VertexProperty', '@value': {'id': {'@type': 'g:Int32', '@value': 544016139}, 'value': '0002-1990-2326-2994', 'label': 'account_number'}}], 'last_name': [{'@type': 'g:VertexProperty', '@value': {'id': {'@type': 'g:Int32', '@value': -1616372909}, 'value': 'Law-Yone', 'label': 'last_name'}}], 'first_name': [{'@type': 'g:VertexProperty', '@value': {'id': {'@type': 'g:Int32', '@value': -451458550}, 'value': 'Eric', 'label': 'first_name'}}]}}}
def flatten(d, c = [], p = []):
t, f = [], []
for a, b in d.items():
(t if not isinstance(b, (dict, list)) else f).append((p+[a], b))
if not f:
yield {'.'.join(a):b for a, b in (c+t)}
else:
for a, b in f:
if isinstance(b, dict):
yield from flatten(b, c=c+t, p = a)
else:
for i in b:
yield from flatten(i, c=c+t, p = a)
d = collections.defaultdict(dict)
for i in flatten(data):
d[i['@value.id']].update(i)
kv = [['@type', '@type'], ['@value.id', '@value.id'], ['@value.label', '@value.label'], ['@value.properties.account_number.@value.id.@value', 'account_number.id'], ['@value.properties.account_number.@value.value', 'account_number.value'], ['@value.properties.last_name.@value.id.@value', 'last_name.id'], ['@value.properties.last_name.@value.value', 'last_name.value'], ['@value.properties.first_name.@value.id.@value', 'first_name.id'], ['@value.properties.first_name.@value.value', 'first_name.value']]
df = pd.DataFrame([{j:b[k] for k, j in kv} for b in d.values()])
Выход:
@type @value.id @value.label ... last_name.value first_name.id first_name.value
0 g:Vertex account-2199023262994 Account ... Law-Yone -451458550 Eric
[1 rows x 9 columns]