Я предлагаю создать три кадра данных и объединить их после. Кроме того, некоторые данные вложены в списки, вложены в dicts и вложены в списки. какое-то путешествие. Лично я использую библиотеку (jmespath), чтобы облегчить путешествие, и ИМХО, проще. как я сказал лично. здесь идет:
import jmespath
from collections import defaultdict
Сначала мы создадим фрейм данных для идентификаторов; вложение здесь не так глубоко, понимание списка (хорошо, понимание вложенного списка) должно сработать, плюс здесь более разумный подход:
df1 = pd.DataFrame({key:value
for key,value
in entry['count'].items()
if key not in ('customEvents','item')}
for entry in event_records)
df1
old_id new_id event_id event_time value quantity unique_id
0 123 456 111 1200 1.0 1 222
1 567 789 333 1400 1.0 1 444
Второй кадр данных для извлечения - это ' В виде'; это то место, где jmespath вступает в игру, поскольку позволяет легко проходить по вложенным спискам / диктам. Вы могли бы написать здесь понимание вложенного списка, но jmespath позволяет нам избежать этой вложенности:
путь к customEvents: list -> dict -> count -> customEvents -> list<br>
ключи доступны в jmespath через символ точки (.), в то время как списки доступны через символ скобок ([])
As =jmespath.compile('[].count.customEvents[]')
out = As.search(event_records)
print(out)
[{'item': 'event#custom', 'type': 'A3', 'value': ''},
{'item': 'event#custom', 'type': 'A4', 'value': '11AA'},
{'item': 'event#custom', 'type': 'A6', 'value': 'AAB1'},
{'item': 'event#custom', 'type': 'A9', 'value': ''},
{'item': 'event#custom', 'type': 'A10', 'value': '10.5'},
{'item': 'event#custom', 'type': 'A11', 'value': 'ABC'},
{'item': 'event#custom', 'type': 'A12', 'value': 'NYR'},
{'item': 'event#custom', 'type': 'A13', 'value': 'NYR'},
{'item': 'event#custom', 'type': 'A14', 'value': 'NYR'},
{'item': 'event#custom', 'type': 'A3', 'value': ''},
{'item': 'event#custom', 'type': 'A4', 'value': '22BB'},
{'item': 'event#custom', 'type': 'A6', 'value': 'CCD1'},
{'item': 'event#custom', 'type': 'A9', 'value': ''},
{'item': 'event#custom', 'type': 'A10', 'value': '20.5'},
{'item': 'event#custom', 'type': 'A11', 'value': 'ABC'},
{'item': 'event#custom', 'type': 'A12', 'value': 'NYR'},
{'item': 'event#custom', 'type': 'A13', 'value': 'NYR'},
{'item': 'event#custom', 'type': 'A14', 'value': 'NYR'}]
далее, мы используем опцию defaultdict для извлечения ключей типа и значения
d = defaultdict(list)
for i in out:
d[i['type']].append(i['value'])
print(d)
defaultdict(list,
{'A3': ['', ''],
'A4': ['11AA', '22BB'],
'A6': ['AAB1', 'CCD1'],
'A9': ['', ''],
'A10': ['10.5', '20.5'],
'A11': ['ABC', 'ABC'],
'A12': ['NYR', 'NYR'],
'A13': ['NYR', 'NYR'],
'A14': ['NYR', 'NYR']})
для чтения их в фрейм данных :
df2 = pd.DataFrame(d)
df2
A3 A4 A6 A9 A10 A11 A12 A13 A14
0 11AA AAB1 10.5 ABC NYR NYR NYR
1 22BB CCD1 20.5 ABC NYR NYR NYR
третья часть предназначена для извлечения данных об ошибках: здесь применима та же концепция []
для списков и .
для ключей; тем не менее, мы можем вернуть наши данные в виде пары key:value
, например: dict:
errors = jmespath.compile('[].errors[].{response:response,feedback:feedback}')
err = errors.search(event_records)
print(err)
[{'response': 'NONE', 'feedback': 'Event not found'}]
, считанный в фрейм данных:
df3 = pd.DataFrame(err)
df3
response feedback
0 NONE Event not found
и мы в конце - объединить кадры данных по столбцам:
result = pd.concat([df1,df2,df3],axis = 1)
old_id new_id event_id event_time value quantity unique_id A3 A4 A6 A9 A10 A11 A12 A13 A14 response feedback
0 123 456 111 1200 1.0 1 222 11AA AAB1 10.5 ABC NYR NYR NYR NONE Event not found
1 567 789 333 1400 1.0 1 444 22BB CCD1 20.5 ABC NYR NYR NYR NaN NaN