Я пытаюсь преобразовать большой файл JSON в CSV, но поле, в котором мне нужно иметь возможность сортировать данные в электронной таблице, находится в одной ячейке всякий раз, когда я конвертирую его в CSV/нормализую JSON. Главное, что мне нужно, это hits
список словарей, которые не должны находиться в одной ячейке, когда я конвертирую его в CSV.
(Структура: словарь словарей, который содержит список словарей)
Вот пример того, как будет выглядеть JSON: https://pastebin.com/VA5mfhfB
Вот как я пытался это сделать (и что дает какой-то результат):
df = pd.json_normalize(boss_dictionary)
df.to_csv(r'data.csv', index=None)
Я пытался указать параметр record_path
, но поскольку нет «единого» boss_id (заранее множество чисел), я не могу понять, как нормализовать hits
список словарей.
Еще одна вещь, которую я пробовал:
df = pd.read_json('data.json')
df.to_csv(r'data.csv', index=None)
Что делает что-то похожее на то, что мне нужно, но не то, что мне действительно нужно. Список попаданий находится только в одной ячейке, а не нормализован.
Что я пытался исправить:
Я попытался нормализовать его с помощью самого словаря и прочитать его из JSON.
Я читал документацию по json_normalize
, но никакие параметры meta
или record_path
не давали мне никакого результата, который не вызывал бы исключения.
Использование json_normalize с композицией списка на основе ключей. Наконец слиться и взорваться.
from ast import literal_eval
import pandas as pd
data = literal_eval(open("/path/to/file/data.txt").read())
df_meta = (
pd
.concat([pd.json_normalize(data=data[x]) for x in data], keys=data.keys())
.droplevel(level=1)
.reset_index(names = "id")
)
df_records = (
pd
.concat([pd.json_normalize(data=data[x], record_path=["hits"]) for x in data], keys=data.keys())
.droplevel(level=1)
.reset_index(names = "id")
)
df_final = pd.merge(left=df_meta, right=df_records).drop(columns = "hits")
df_final = df_final.explode("hp_list").reset_index(drop=True)
Переменная «данные» в моем ответе - это json из вставки или boss_dictionary
Спасибо за ответ! В настоящее время я получаю сообщение об ошибке .concat([pd.json_normalize(data=data[x]) for x in data], keys=data.keys()) --- NotImplementedError. Я определенно предполагаю, что это связано с моей реализацией, а не с вашей, но я оставлю ссылку на pastebin всего моего текущего кода, и вы, возможно, сможете обнаружить что-то, чего я не могу. Я использую pandas как новичок, который только что попытался изучить его с помощью документов, и это моя первая попытка использовать его в проекте в реальном времени. pastebin.com/T3TU5Qgf Обратите внимание, что первой вставкой (OP) были данные json.
Я просто скопировал pastebin json в файл с именем data.txt (заменил true на True, а false на False) и прочитал файл с помощью: from ast import literal_eval. data = literal_eval(open("/path/to/file/data.txt").read())
аааааа у меня работает! единственное несоответствие в том, что он записывает каждое попадание вместе с каждым хп в списке хп. Я предполагаю, что df_final.explore("hp_list") должен предотвратить это, но вот как выглядит csv для одного обращения: pastebin.com/CkejHEB6. Как бы вы изменили его, чтобы в идеале просто удалить hp_list из фрейма данных? Спасибо за постоянную помощь, Джейсон!
df_final = pd.merge(left=df_meta, right=df_records).drop(columns=["hits", "hp_list"]) # df_final = df_final.explode("hp_list").reset_index(drop=True) print(df_final )
Как этот вызов из файла data.json или boss_dictionary? Я не совсем уверен, как связать ваш ответ с настройкой фрейма данных, которая у меня была ранее. т.е. Что мне нужно отредактировать в том, что у меня есть сейчас, чтобы это соответствовало вашему замечательному ответу, ха-ха