Как сохранить вложенный JSON, который находится в списке, в текстовый файл, используя Python?
Я создаю вложенный JSON, и я храню его в списке объектов. Вот мой код, который получает правильный иерархический JSON, как и предполагалось.
Пример данных:
источник данных, datasource_cnt, категория, category_cnt, подкатегория, subcategory_cnt Бюро статистики труда,44, Занятость и заработная плата,44, Занятость и заработная плата, 44
import pandas as pd
df=pd.read_csv('queryhive16273.csv')
def split_df(df):
for (vendor, count), df_vendor in df.groupby(["datasource", "datasource_cnt"]):
yield {
"vendor_name": vendor,
"count": count,
"categories": list(split_category(df_vendor))
}
def split_category(df_vendor):
for (category, count), df_category in df_vendor.groupby(
["category", "category_cnt"]
):
yield {
"name": category,
"count": count,
"subCategories": list(split_subcategory(df_category)),
}
def split_subcategory(df_category):
for (subcategory, count), df_subcategory in df_category.groupby(
["subcategory", "subcategory_cnt"]
):
yield {
"count": count,
"name": subcategory,
}
abc=list(split_df(df))
ABC содержит данные, как показано ниже. Это намеченный результат.
[{
'count': 44,
'vendor_name': 'Bureau of Labor Statistics',
'categories': [{
'count': 44,
'name': 'Employment and wages',
'subCategories': [{
'count': 44,
'name': 'Employment and wages'
}]
}]
}]
Сейчас я пытаюсь сохранить его в файл JSON.
with open('your_file2.json', 'w') as f:
for item in abc:
f.write("%s\n" % item)
#f.write(abc)
Здесь возникает проблема. Это записывает данные таким способом (см. Ниже), который не является допустимым форматом JSON. Если я пытаюсь использовать JSON дампа, он дает "Ошибка сериализации JSON"
Не могли бы вы помочь мне здесь.
{
'count': 44,
'vendor_name': 'Bureau of Labor Statistics',
'categories': [{
'count': 44,
'name': 'Employment and wages',
'subCategories': [{
'count': 44,
'name': 'Employment and wages'
}]
}]
}
Ожидаемый результат:
[{
"count": 44,
"vendor_name": "Bureau of Labor Statistics",
"categories": [{
"count": 44,
"name": "Employment and wages",
"subCategories": [{
"count": 44,
"name": "Employment and wages"
}]
}]
}]
2 ответа
Используя ваши данные и PSL json
дает мне:
TypeError: Object of type 'int64' is not JSON serializable
Это просто означает, что какой-то объект numpy живет в вашей вложенной структуре и не имеет encode
способ конвертировать его для сериализации JSON.
Для того, чтобы ваш код работал, достаточно заставить codede использовать преобразование строк, когда ему не хватает самого объекта:
import io
d = io.StringIO("datasource,datasource_cnt,category,category_cnt,subcategory,subcategory_cnt\nBureau of Labor Statistics,44,Employment and wages,44,Employment and wages,44")
df=pd.read_csv(d)
abc=list(split_df(df))
import json
json.dumps(abc, default=str)
Возвращает действительный JSON (но с int
конвертирован в str
):
'[{"vendor_name": "Bureau of Labor Statistics", "count": "44", "categories": [{"name": "Employment and wages", "count": "44", "subCategories": [{"count": "44", "name": "Employment and wages"}]}]}]'
Если это не соответствует вашим потребностям, используйте специальный кодер:
import numpy as np
class MyEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, np.int64):
return int(obj)
return json.JSONEncoder.default(self, obj)
json.dumps(abc, cls=MyEncoder)
Это возвращает запрошенный JSON:
'[{"vendor_name": "Bureau of Labor Statistics", "count": 44, "categories": [{"name": "Employment and wages", "count": 44, "subCategories": [{"count": 44, "name": "Employment and wages"}]}]}]'
Другой вариант - напрямую преобразовать ваши данные перед кодированием:
def split_category(df_vendor):
for (category, count), df_category in df_vendor.groupby(
["category", "category_cnt"]
):
yield {
"name": category,
"count": int(count), # Cast here before encoding
"subCategories": list(split_subcategory(df_category)),
}
import json
data = [{
'count': 44,
'vendor_name': 'Bureau of Labor Statistics',
'categories': [{
'count': 44,
'name': 'Employment and wages',
'subCategories': [{
'count': 44,
'name': 'Employment and wages'
}]
}]
}]
with open('your_file2.json', 'w') as f:
json.dump(data, f, indent=2)
создает правильный файл JSON:
[
{
"count": 44,
"vendor_name": "Bureau of Labor Statistics",
"categories": [
{
"count": 44,
"name": "Employment and wages",
"subCategories": [
{
"count": 44,
"name": "Employment and wages"
}
]
}
]
}
]