Могу ли я загрузить данные только в часть файла json?

#python #json #file #dictionary

Вопрос:

Мне интересно, есть ли какой-либо способ обновить файл json без необходимости полностью переписывать файл json. Как показано в примере ниже, сначала мне пришлось извлечь все данные из файла json, затем добавить/ отредактировать исходные данные, а затем переписать новый словарь данных поверх исходного файла. Можно ли просто отредактировать несколько строк файла json напрямую?

У меня есть основной файл и файл json, которые выглядят следующим образом:

ОСНОВНОЙ ФАЙЛ

 import json

with open('animals.json') as f:
    data = json.load(f)

attributes = {"Food": "", "Size": "", "Habitat": ""}

data["Animal 1"]["Food"] = "Meat"
data["Animal 1"]["Size"] = "Medium"
data["Animal 1"]["Habitat"] = "Savannah"

attributes["Food"] = "Nuts"
attributes["Size"] = "Small"
attributes["Habitat"] = "Forest"
data["Animal 3"] =  dict(attributes)

# attributes["Food"] = "Plankton"
# attributes["Size"] = "Large"
# attributes["Habitat"] = "Ocean"
# data["Animal 2"] =  dict(attributes)

with open('animals.json', 'w') as f:
    json.dump(data, f, indent=4)
 

ФАЙЛ JSON

 {
    "Animal 1": {
        "Food": "Banana",
        "Size": "Medium",
        "Habitat": "Jungle"
    },
    "Animal 2": {
        "Food": "Plankton",
        "Size": "Large",
        "Habitat": "Ocean"
    }
}
 

В настоящее время код обновляет файл json (атрибуты животного 1 и добавляет Животное 3), чтобы он выглядел следующим образом:

 {
    "Animal 1": {
        "Food": "Meat",
        "Size": "Medium",
        "Habitat": "Savannah"
    },
    "Animal 2": {
        "Food": "Plankton",
        "Size": "Large",
        "Habitat": "Ocean"
    },
    "Animal 3": {
        "Food": "Nuts",
        "Size": "Small",
        "Habitat": "Forest"
    }
}
 

Существуют ли какие-либо альтернативы этому методу?

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

1. Если вы хотите сделать это масштабируемым, я бы, вероятно, использовал что-то вроде sqlite, что дало бы вам возможность выбирать конкретные записи и редактировать их.

2. Это не имеет никакого отношения к JSON; файлы так не работают. Кроме того, все это не имеет ничего общего с «загрузкой», что означает передачу вашего файла с вашего компьютера на сервер.

3. Поэтому я не могу использовать его с файлами json @dir

4. @ChristopherOjo Я понятия не имею, каковы ваши долгосрочные цели, но чтобы ответить на этот вопрос: нет. Вам придется каждый раз переписывать файл заново.

5. «вся проблема в «загрузке» в «файл json» «» Нет, это не так. Слово «загрузка» означает не то, что вы, по-видимому, думаете, что оно означает .

Ответ №1:

Я предполагаю, что вы увеличите масштаб процесса с гораздо большим количеством данных, поэтому перезапись данных json можно легко выполнить с помощью фреймов данных pandas. Главное здесь то, что вам не нужно беспокоиться о том, что каждое поле json будет обновляться, как вы показали в своем коде. Я не буду заниматься сохранением/записью файлов, так как это не проблема. Если бы не информация о json, при таком подходе решение занимало бы всего 6 строк кода. Пошаговое объяснение я показываю после полного кода.

Кстати, вы также можете читать из файла json напрямую, используя pd.read_json('file_name.json') и записывая в него datraframe_object.to_json('file_name.json') .

Полный код для тех, кто хочет воспроизвести:

 import json
import pandas as pd

original_json = {
    "Animal 1": {
        "Food": "Banana",
        "Size": "Medium",
        "Habitat": "Jungle"
    },
    "Animal 2": {
        "Food": "Plankton",
        "Size": "Large",
        "Habitat": "Ocean"
    }
}

overwrite_json = {
    "Animal 1": {
        "Food": "Meat",
        "Size": "Medium",
        "Habitat": "Savannah"
    },
    "Animal 2": {
        "Food": "Plankton",
        "Size": "Large",
        "Habitat": "Ocean"
    },
    "Animal 3": {
        "Food": "Nuts",
        "Size": "Small",
        "Habitat": "Forest"
    }
}

#here the six lines to get your updated json info
original_frame = pd.DataFrame(original_json).T
overwrite_frame = pd.DataFrame(overwrite_json).T
original_frame['index'] = original_frame.index
overwrite_frame['index'] = overwrite_frame.index

updated_frame = original_frame.merge(overwrite_frame,how='right').set_index('index')
final_json = updated_frame.to_json(orient='index',indent=4)
print(final_json)
 

Вывод:

 {
    "Animal 1":{
        "Food":"Meat",
        "Size":"Medium",
        "Habitat":"Savannah"
    },
    "Animal 2":{
        "Food":"Plankton",
        "Size":"Large",
        "Habitat":"Ocean"
    },
    "Animal 3":{
        "Food":"Nuts",
        "Size":"Small",
        "Habitat":"Forest"
    }
}
 

Пошаговое объяснение:

  1. Импортируйте панду, которая обычно используется для обработки данных, поэтому она хорошо документирована и используется многими.
 import json
import pandas as pd
 
  1. Здесь я предполагаю, что вы сделаете свою вещь с открытым файлом. Для простоты я просто назначу объекты json с предоставленной вами информацией.
 original_json = {
    "Animal 1": {
        "Food": "Banana",
        "Size": "Medium",
        "Habitat": "Jungle"
    },
    "Animal 2": {
        "Food": "Plankton",
        "Size": "Large",
        "Habitat": "Ocean"
    }
}

overwrite_json = {
    "Animal 1": {
        "Food": "Meat",
        "Size": "Medium",
        "Habitat": "Savannah"
    },
    "Animal 2": {
        "Food": "Plankton",
        "Size": "Large",
        "Habitat": "Ocean"
    },
    "Animal 3": {
        "Food": "Nuts",
        "Size": "Small",
        "Habitat": "Forest"
    }
}
 
  1. Создайте фреймы данных pandas из информации json. Я перенес ( .T ) сюда, чтобы сохранить вашу первоначальную ориентацию на записи json.
 original_frame = pd.DataFrame(original_json).T
overwrite_frame = pd.DataFrame(overwrite_json).T
 

Кадры данных выглядят так. Они проиндексированы на «Животное 1», «Животное 2» и так далее:

 print(original_frame)
            Food    Size   Habitat     
Animal 1    Banana  Medium  Jungle  
Animal 2  Plankton   Large   Ocean

print(overwrite_frame)
             Food    Size   Habitat     
Animal 1      Meat  Medium  Savannah  
Animal 2  Plankton   Large     Ocean  
Animal 3      Nuts   Small    Forest
 
  1. Сохраните индексы каждого фрейма данных в новом столбце для последующего использования.
 original_frame['index'] = original_frame.index
overwrite_frame['index'] = overwrite_frame.index
#example of 'index' column created
print(original_frame)
           Food    Size    Habitat     index
Animal 1    Banana  Medium  Jungle  Animal 1
Animal 2  Plankton   Large   Ocean  Animal 2
 
  1. Затем мы объединяем два кадра данных, перезаписывая исходный кадр с кадром перезаписи. Смотрите, что я использую how='right' , чтобы отдать предпочтение overwrite_frame и set_index использовать ранее сохраненные столбцы индекса.
 updated_frame = original_frame.merge(overwrite_frame,how='right').set_index('index')
print(update_frame)
             Food    Size   Habitat
index                               
Animal 1      Meat  Medium  Savannah
Animal 2  Plankton   Large     Ocean
Animal 3      Nuts   Small    Forest
 
  1. Затем просто сгенерируйте новый json из полученного фрейма данных
 final_json = updated_frame.to_json(orient='index',indent=4)
print(final_json)
{
    "Animal 1":{
        "Food":"Meat",
        "Size":"Medium",
        "Habitat":"Savannah"
    },
    "Animal 2":{
        "Food":"Plankton",
        "Size":"Large",
        "Habitat":"Ocean"
    },
    "Animal 3":{
        "Food":"Nuts",
        "Size":"Small",
        "Habitat":"Forest"
    }
}
 

Если я правильно понял ваш вопрос, это решит ваше узкое место!