首页 > 解决方案 > 我可以只将数据上传到 json 文件的一部分吗?

问题描述

我想知道是否有任何方法可以更新 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)

文件

{
    "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"
    }
}

这种方法有其他选择吗?

标签: pythonjsonfiledictionary

解决方案


我想你会用更多的数据来扩展这个过程,所以这个json 数据覆盖可以很容易地通过使用pandas dataframes来实现。这里的主要内容是您不必担心每个 json 字段都会像您在代码中显示的那样被更新。我不会通过保存/写入文件的事情,因为这不是问题。如果不是 json 信息,则该解决方案使用这种方法最多只需要 6 行代码。我在完整代码之后显示的分步说明。

顺便说一句,您也可以通过使用pd.read_json('file_name.json')和写入直接从 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. 导入 pandas,它通常用于数据科学,因此它有很好的文档记录并被许多人使用。
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. 创建 json 信息的 pandas 数据框。我.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. 然后我们合并两个数据帧,用 overwrite_frame 覆盖 original_frame。看到我how='right'用来优先使用overwrite_frameset_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"
    }
}

如果我的问题是正确的,这将解决您的瓶颈!


推荐阅读