如何在python中规范化复杂的嵌套json?

时间:2017-04-07 14:18:23

标签: python json loops nested-loops

我试图在python中规范化复杂的嵌套json但我无法解析所有对象。

我正在引用此页面中的代码。 https://medium.com/@amirziai/flattening-json-objects-in-python-f5343c794b10

sample_object = {'Name':'John', 'Location':{'City':'Los Angeles','State':'CA'}, 'hobbies':['Music', 'Running']}

def flatten_json(y):
    out = {}

    def flatten(x, name=''):  

        if type(x) is dict:
            for a in x:
                flatten(x[a], name + a + '_')
        elif type(x) is list:
            for a in x:
                flatten(a, name)
        else:
            out[name[:-1]] = x

    flatten(y)

    return out
flat = flatten_json(sample_object)
print json_normalize(flat)

返回结果

Name | Location_City | Location_State | Hobbies
-----+---------------+----------------+--------
John | Los Angeles   | CA             | Running

预期结果:

Name | Location_City | Location_State | Hobbies
-----+---------------+----------------+--------
John | Los Angeles   | CA             | Running
John | Los Angeles   | CA             | Music

1 个答案:

答案 0 :(得分:1)

您遇到的问题来自以下部分

elif type(x) is list:
    for a in x:
        flatten(a, name)

因为您没有更改列表中每个元素的名称,所以每个下一个元素都将覆盖前一个元素的赋值,因此只有最后一个元素将显示在输出中。

应用于此示例,当展平功能到达列表'爱好'时,它将首先将名称'hobbies'分配给元素'Music'并将其发送到输出。元素'Music'之后,列表中的下一个元素是'Running',它也将被命名为'hobbies'。当此元素发送到输出时,它会注意到名称“爱好”已经存在,并且它将覆盖值“运行”的值“音乐”。

为了防止这种情况,您引用的链接中的脚本使用以下代码将de array的索引附加到名称,从而为数组的每个元素创建唯一的名称。

elif type(x) is list:
    i = 0
    for a in x:
        flatten(a, name + str(i) + ' ')
        i += 1

这将为数据创建额外的“列”,而不是新行。如果后者是你想要的,你将不得不改变功能的设置方式。一种方法是调整函数以返回json列表(原始json中每个列表元素一个)。

一个额外的注意事项:我建议在提交问题时更加谨慎地使用coppying代码。在这种情况下缩进是有点的,因为你遗漏了导入json_normalize的部分,所以你从pandas导入它的每个人都可能不完全清楚

from pandas.io.json import json_normalize