【问题标题】:Printing parent data along with child data of nested JSON打印父数据以及嵌套 JSON 的子数据
【发布时间】:2018-07-04 20:45:55
【问题描述】:

我有以下类型的 JSON。在另一个表中,我有 JSONPaths,它告诉我获取某些值。如果我要获取子元素的值,我需要获取所有对应的父属性值,并将所有这些值作为一行存储在数据框中。

{
  "Parent": {
    "Name": "Bob",
    "Age": "80",
    "Children": [
      {
        "Name": "Michael",
        "Gender":"M",
        "Children": [
          {
            "Name": "Ezee",
            "Gender": "M",
            "Age": 20
          },
          {
            "Name": "Ezee",
            "Gender": "M",
            "Age": 28,
            "Children": [
              {
                "Name": "Dre",
                "Age": 1
              },
              {
                "Name": "George",
                "Age": 2
              }
            ]
          }
        ],
        "Age": 50,
        "MiddleName": "Jay"
      },
      {
        "Name": "Justin",
        "Gender": "M",
        "Children": [
          {
            "Name": "Emily",
            "Age": 18,
            "Gender": "F"
          }
        ],
        "Age": 45
      }
    ]
  }
}

假设我需要获取JSON路径的值:Parent/Children/0/Children/0/Name,我需要获取对应父母的姓名、年龄等属性值(Parent/Children/0/[姓名或年龄等) .]) 并将上述所有值存储为一行。

目前,我可以通过传递相关路径分别获取父值,并通过传递该路径分别获取子值。

def findValue(path, json_data):
    paths = path.split("/")    
    data = json_data
    for i in range(0,len(paths)):
        if isinstance(data, list):
            paths[i]=int(paths[i])
            data = data[paths[i]]
        else:
            data = data.get(paths[i])
    return data

我怎样才能做到这一点?

【问题讨论】:

    标签: python json


    【解决方案1】:

    要获取最后一个父级,您需要遍历路径直到您最后一次关注Children 列表。

    即给定您的路径:'Parent/Children/0/Children/0/Name' 您希望在 'Parent/Children/0' 返回父级的数据。

    这在 Python 中很容易做到,只需将 path 字符串切到子字符串 /Children 的最后一次出现:

    path[:path.rfind('/Children')]
    

    然后,您可以使用与当前获取父级数据类似的代码:

    parent = json_data
    path = path[:path.rfind('/Children')]
    for attr in path.split('/'):
        parent = parent[int(attr) if isinstance(parent, list) else attr]
    

    对于这个例子,它会给我们parent

    {
      "Name": "Michael",
      "Gender": "M",
      "Children": [
        {
          "Name": "Ezee",
          "Gender": "M",
          "Age": 20
        },
        {
          "Name": "Ezee",
          "Gender": "M",
          "Age": 28,
          "Children": [
            {
              "Name": "Dre",
              "Age": 1
            },
            {
              "Name": "George",
              "Age": 2
            }
          ]
        }
      ],
      "Age": 50,
      "MiddleName": "Jay"
    }
    

    为了完整地完成您的问题,如果您希望此人的属性(没有他们的 Children 列表)作为单行,您必须决定以固定方式(例如按字母顺序)存储它们,然后您可以使用 dict 的.items() 方法将这些提取到正确的格式:

    [v for k,v in sorted(t for t in parent.items() if t[0] != 'Children')]
    

    给予,例如:

    [50, 'M', 'Jay', 'Michael']
    #Age, Gender, Middle Name, Name
    

    哦,如果您愿意,可以将整个第一个代码压缩为单行代码:

    __import__('functools').reduce(lambda d,a:d[int(a) if isintance(d,list) else a], path[:path.rfind('/Children')].split('/'), json_data)
    

    【讨论】:

      【解决方案2】:

      如果我理解得很好,你想要的只是一个像Parent/Children/0/Children/0/Name 这样的路径,获取其父级相同属性的路径。在这种情况下,它将是Parent/Children/0/Name

      这是我对python解释器的尝试,希望对你有所帮助:

      >>> path = "Parent/Children/0/Children/0/Name"
      >>> path_l = path.split('/')
      >>> rev = path_l[::-1]
      >>> rev
      ['Name', '0', 'Children', '0', 'Children', 'Parent']
      >>> rev.index('Children')
      2
      >>> rev = rev[rev.index('Children')+1:]
      >>> rev
      ['0', 'Children', 'Parent']
      >>> final = rev[::-1] + [path_l[-1]]
      >>> final
      ['Parent', 'Children', '0', 'Name']
      >>> parent_path = '/'.join(final)
      >>> parent_path
      'Parent/Children/0/Name'
      

      然后使用您的函数,您可以将两个值添加到数据框

      >>> df = pandas.DataFrame({'Parent': [], 'Children':[]})
      >>> df.append([parent], [children])
      

      【讨论】:

        猜你喜欢
        • 2022-01-07
        • 2017-06-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-14
        • 2014-08-05
        • 1970-01-01
        • 2017-04-23
        相关资源
        最近更新 更多