#python #json
Вопрос:
В настоящее время у меня есть N входных файлов json, которые все имеют одинаковую структуру, но где N — 1 значения определены как «Нет» для каждого из них. Я хочу объединить их в один json, где, подобно слиянию/исправлению git, он всегда выбирает заданное значение (т. Е. То, которое отличается от «Нет»). Вот пример (вымышленный):
json 1: {'a': 'aaa', ['b': 'None', 'c': 'None']}
json 2: {'a': 'None', ['b': 'bbb', 'c': 'None']}
json 3: {'a': 'None', ['b': 'None', 'c': 'ccc']}
ожидаемый результат: {‘a’: ‘aaa’, [‘b’: ‘bbb’, ‘c’: ‘ccc’]}
Банкомат, я подумываю об использовании zip для всех входных файлов, повторении каждого слова и выборе того, что не является «Нет», для составления выходного файла. Однако я думаю, что должен быть более чистый способ сделать это, которого я сейчас просто не вижу.. Заранее спасибо!
Комментарии:
1. Что вы подразумеваете под чистотой ?
2. обратите внимание, что ваши входные данные для примера *даже не близки к допустимому JSON.
3. О json: Извините за мою ошибку! На самом деле я имел в виду, что скрипты python работают с объектами, которые чем-то похожи на примеры, которые позже превращаются в допустимые json. Я мог бы работать либо с объектами, либо с json, чтобы сформировать желаемый результат с помощью «очистителя». Я имел в виду некоторую обработку, которая не требовала бы явного повторения каждого файла в коде python (даже если он будет обработан таким образом), поэтому код проще поддерживать (у нас есть ~40 таких объектов).
Ответ №1:
Формат ваших файлов json сейчас неверен. Вы должны проверить это и соответствующим образом обновить код. На данный момент я преобразовал ваш json в следующий формат:
json_1 = {"a": "aaa", "b": "None", "c": "None"}
json_2 = {"a": "None", "b": "bbb", "c": "None"}
json_3 = {"a": "None", "b": "None", "c": "ccc"}
Если данные находятся в файлах, вы можете использовать следующую функцию:
import json
f = open ('data.json', "r")
json.load(f.read())
и если данные представлены в строковом формате, вы можете использовать:
import json
json_1 = json.loads('{"a": "aaa", "b": "None", "c": "None"}')
json_2 = json.loads('{"a": "None", "b": "bbb", "c": "None"}')
json_3 = json.loads('{"a": "None", "b": "None", "c": "ccc"}')
Что касается решения, то лучшим вариантом будет перебор файлов json. Альтернативным подходом к решению проблемы было бы предварительно очистить все ключи, которые содержат «Нет», а затем объединить их в один. Один и тот же код для одного и того же является:
json_clean_1 = {k: v for k, v in json_1.items() if v != "None"}
json_clean_2 = {k: v for k, v in json_2.items() if v != "None"}
json_clean_3 = {k: v for k, v in json_3.items() if v != "None"}
output_json = dict(list(json_clean_1.items()) list(json_clean_2.items()) list(json_clean_3.items()))
print(output_json)
Основываясь на комментарии, вы могли бы использовать решение, подобное этому. Это должно дать вам выходной фрейм данных со столбцом, содержащим объединенные значения:
import os
import json
import pandas as pd
# get files
json_files = [
each_file for each_file in os.listdir(".") if each_file.endswith('.json')
]
# read files
dfs = []
for file in json_files:
with open(file) as f:
json_data = pd.json_normalize(json.loads(f.read()))
dfs.append(json_data)
# combine and clean df
combined_df = pd.concat(dfs, ignore_index=True)
cleaned_df = combined_df.replace("None", pd.NA).transpose()
# df with required column
cleaned_df['combined_col'] = cleaned_df[cleaned_df.columns].apply(
lambda x: ','.join(x.dropna().astype(str)), axis=1)
print(cleaned_df)
Комментарии:
1. спасибо вам за ваш ответ! И извините за мою ошибку со стороны json. Чтобы немного прояснить, у нас есть эти объекты, которые позже будут перенесены в допустимые json, и мы можем работать с любым из них для решения этой проблемы. Проблема в том, что в каждом объекте/json гораздо больше ключей, и некоторые из них находятся внутри списков… и в настоящее время у нас более 40 json/объектов, поэтому я надеялся, что смогу сделать это в меньшем количестве и более лаконичных строк
2. @Nadal Я обновил свое решение на основе этого. Дайте мне знать, если это поможет
3. Большое вам спасибо за помощь! Я смог изменить то, что вы предоставили, в рабочее решение