Отображение вложенного JSON в виде фрейма данных со всеми значениями в их собственном столбце

#python

#питон

Вопрос:

Я обрабатываю набор данных, полученный из JSON, чтобы получить следующий результирующий формат. Ниже приведены мои ожидания:

 category type value value_type mandatory 0 business-activities activities-hot-work true boolean true 1 business-employees employees-full-time 6 integer true  

То, что я получаю, — это следующее от df:

 category type value validation 0 business-activities activities-hot-work true [{'value_type': 'boolean'}, {'mandatory': True}] 1 business-employees employees-full-time 6 [{'value_type': 'integer'}, {'mandatory': True}]  

Вот мой сценарий

 import json import pandas as pd  # broker data received with open(r'C:UsersmattlOneDriveEverythingDocumentsData files for Python  Devcharacteristic_values.json') as data_in:  data = json.load(data_in) data_inbound = pd.json_normalize(data, 'characteristics', record_prefix='')  # validation data used to process validation on data received with open(r'C:UsersmattlOneDriveEverythingDocumentsData files for Python Devcharacteristic_validation.json') as data_val: data = json.load(data_val) data_validation = pd.json_normalize(data, 'characteristics', record_prefix='')  # merge validation with broker data and normalise the data df = pd.merge(data_inbound, data_validation, on=['category','type'])  print(df)  # Show results print('Merged and exploded Result') dfa = df.explode('validation') print(dfa)  

Мои входные файлы

Characteristic_values.json

 {  "characteristics" :[  {  "category" : "business-activities",  "type" : "activities-hot-work",  "value" : "true"  },  {  "category" : "business-employees",  "type" : "employees-full-time",  "value" : "6"  }  ] }  

Characteristic_validation.json

 {  "characteristics": [{  "category": "business-activities",  "type": "activities-hot-work",  "validation": [{  "value_type": "boolean"  }, {  "mandatory": true  }]  },  {  "category": "business-employees",  "type": "employees-full-time",  "validation": [{  "value_type": "integer"  },  {  "mandatory ": true  }  ]  }  ]  }  

Что я уже пробовал?

characteristics_data = pd.json_normalize(data=df, record_path='validation', meta=['category', 'type', 'value']) Я изменил тот, который работает в учебнике по обработке вложенного JSON, но он выдает ошибку, которую я не могу понять, но, возможно, на правильном пути.

Сообщения об ошибках

 File "C:UsersmattlPycharmProjectsjsonValidationmain.py", line 25, in lt;modulegt; characteristics_data = pd.json_normalize(data=df, record_path='validation',  File "C:UsersmattlPycharmProjectsjsonValidationvenvlibsite-packagespandasiojson_normalize.py", line 504, in _json_normalize _recursive_extract(data, record_path, {}, level=0)  File "C:UsersmattlPycharmProjectsjsonValidationvenvlibsite-packagespandasiojson_normalize.py", line 477, in _recursive_extract recs = _pull_records(obj, path[0])  File "C:UsersmattlPycharmProjectsjsonValidationvenvlibsite-packagespandasiojson_normalize.py", line 399, in _pull_records result = _pull_field(js, spec)  File "C:UsersmattlPycharmProjectsjsonValidationvenvlibsite-packagespandasiojson_normalize.py", line 390, in _pull_field result = result[spec] TypeError: string indices must be integers  

Я надеюсь, что предоставил достаточно информации, чтобы объяснить свою проблему — спасибо

Комментарии:

1. вы заметите, что я также попробовал dfa = df.explode('validation') , но это дает мне 4 строки, и все равно значения, содержащиеся в объектах, непригодны для использования. Я оставил его на всякий случай, если это направление окажется лучше, чем нормализация

2. Я также пробовал result = pd.json_normalize(df, 'validation', ['category', 'type', 'value' ['value_type', 'mandatory']]) , но TypeError: string indices must be integers снова ошибался с

Ответ №1:

С помощью вашего фрейма данных df

 category type value validation 0 business-activities activities-hot-work true [{'value_type': 'boolean'}, {'mandatory': True}] 1 business-employees employees-full-time 6 [{'value_type': 'integer'}, {'mandatory': True}]  

вы могли бы сделать

 df = pd.concat(  [  df.drop(columns="validation"),  pd.DataFrame({**l[0], **l[1]} for l in df.validation)  ],  axis=1 )  

или немного более общий

 from itertools import chain  df = pd.concat(  [  df.drop(columns="validation"),  pd.DataFrame(dict(chain(*(d.items() for d in l))) for l in df.validation)  ],  axis=1 )  

Результат:

 category type value value_type mandatory 0 business-activities activities-hot-work true boolean True 1 business-employees employees-full-time 6 integer True  

Комментарии:

1. Это звучит потрясающе, я попробую это позже этим вечером и дам вам знать, основываясь на ожидаемом rssult, выглядит идеально, спасибо

2. спасибо, работает отлично, я использовал более общий подход