我有以下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
,我需要获取相应父级(父级/子级/ 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
我该如何实现?
答案 0 :(得分:1)
如果我理解得很好,将为您想要的所有路径提供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])
答案 1 :(得分: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
列表)排成一行,则必须决定以固定方式(例如,按字母顺序)存储它们,并且那么您可以使用字典的.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)