【问题标题】:flatten JSON dataframe in python在python中展平JSON数据框
【发布时间】:2022-01-16 19:31:39
【问题描述】:

我提出了一个 API 请求,我收到了下面嵌套格式的 JSON(以及我所期望的)。

我不需要经常扁平化 JSON 数据,而当我这样做时,我只需使用 Json_normalize。 我尝试过使用json_normalize,但这次没有任何效果。

任何帮助将不胜感激。

澄清一下,一旦我提出请求,json 数据就会进入数据帧。这些字段应该成为列。 最终结果是具有以下列的表:id、field1、field 2 等。

#ACTUAL
[
    {
        "id": 1000,
        "tableName": {
            "": {
                "field1": null,
                "field2": null,
            }
        }
    },
{
        "id": 1001,
        "tableNameTwo": {
            "": {
                "field1": null,
                "field2": null,
            }
        }
    }

]


#EXPECTED
[
    {
         "id": 1000,
         "field1": null,
         "field2": null,
    },
{
         "id": 1001,
         "field1": null,
         "field1": null,
    },
...
]

【问题讨论】:

  • ` "": { "field": null, "field": null, "field": null, "field": null, "field": null, "field": null, " field": null, "field": null, "field": null }` 这是非常奇怪的 json。我会说每个字段都应该有自己的字段名称。特别是当 json 组映射到 python 中的字典时。删除重复键的位置。
  • 对不起,我应该澄清一下我已经匿名了数据。他们确实有自己的字段名称。通过的数据很好。它纯粹是嵌套问题。

标签: python json python-3.x pandas dataframe


【解决方案1】:

更新:下面的代码可以为您工作。

注意:我已将您的输入数据从null 修改为None

list = [
    {
        "id": 1000,
        "tableName": {
            "": {
                "field1": None,
                "field2": None,
            }
        }
    },
{
        "id": 1001,
        "tableNameTwo": {
            "": {
                "field1": None,
                "field2": None,
            }
        }
    }

]

flatList = []
for i in list:
    tempDict = {}
    for key, value in i.items():
        if key.startswith('table'):
            for m, n in value[''].items():
                tempDict.update({m: n})
        else:
            tempDict.update({key:value})

    flatList.append(tempDict)

print(flatList)

输出:

[
  {
    'id': 1000,
    'field1': None,
    'field2': None
  },
  {
    'id': 1001,
    'field1': None,
    'field2': None
  }
]

如果代码有任何缺陷,贡献者请添加评论,答案可以更新。

【讨论】:

  • 当我运行这个 sn-p 它给我这个错误:“异常:AttributeError:'str'对象没有属性'items'”
  • @datadatadata,我已经用你更新的问题更新了代码,它对我有用,如果这对你有用,请告诉我。
【解决方案2】:

扁平化 json 响应几乎总是不好的做法,例如,如果嵌套对象中有键重复(大多数情况下嵌套对象都有自己的 id),你怎么能解决这个冲突?

但是,如果此问题不是用于生产用途,而只是做一些功课等。您可以使用以下代码。我在您的示例中对其进行了测试:

map = [
    {
        "id": 1000,
        "tablename": {
            "": {
                "field1": None,
                "field2": None,
                "field3": None,
                "field4": None,
                "field5": None,
                "field6": None,
                "field7": None,
                "field8": None,
                "field9": None
            }
        }
    }
]
new_map = {}


def flat_json_object(obj):
    for k, v in obj.items():
        if type(v) is dict:
            flat_json_object(v)
        else:
            new_map[k] = v


def flat_json_array(array):
    for obj in array:
        flat_json_object(obj)


flat_json_array(map)

【讨论】:

    【解决方案3】:

    我会推荐以下内容:

    import pandas as pd
    
    your_list = [
        {
            "id": 1000,
            "tablename": {
                "tableZero": {
                    "field0": None,
                    "field1": None,
                    "field2": None,
                }
            }
        }
    ]
    
    df = pd.json_normalize(your_list, sep='_')
    
    print(df.to_dict(orient='records')[0])
    

    这将输出以下字典。

    your_result = {
        "id": 1000,
        "tablename_tableZero_field0": None,
        "tablename_tableZero_field1": None,
        "tablename_tableZero_field2": None,
    }
    

    【讨论】:

    • 太棒了,谢谢你的帮助。当我用一个孤立的样本集测试它时,它工作得很好。但是当我将它合并到我的 Get dataframe req 中时。它给了我这个错误:异常:IndexError:列表索引超出范围
    • 是的,那是因为pandas.DataFrame.get 将返回一个熊猫系列而不是一个列表。您可以执行以下操作:option_with_get_input = input_df.get("jsonColumn").tolist()option_to_list_input = input_df["jsonColumn"].to_list()。只需将其中一个选项放入 json_normalize 方法中,一切都会正常工作。希望有帮助
    • 感谢您的帮助。我现在收到此错误异常:KeyError:“[索引(['field1','field2'...])都在[列]中”
    • 也许您可以分享更多代码,以便我可以在本地复制错误消息。
    猜你喜欢
    • 1970-01-01
    • 2019-03-18
    • 2023-03-07
    • 1970-01-01
    • 1970-01-01
    • 2012-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多