I have been trying to reformat a json file in a way that all the nested data appears as single attributes. So essentially, from json example A, I would get json B that does not contain any of the nested data. How should I go about that?
JSON A:
[
{
"frame_id":1,
"filename":"/content/drive/MyDrive/Clocks/clock.jpg",
"objects": [
{"class_id":74, "name":"clock", "relative_coordinates":{"center_x":0.497010, "center_y":0.561621, "width":0.300727, "height":0.557968}, "confidence":0.754266}
]
},
{
"frame_id":2,
"filename":"/content/drive/MyDrive/Clocks/clock2.jpg",
"objects": [
{"class_id":74, "name":"clock", "relative_coordinates":{"center_x":0.651665, "center_y":0.511030, "width":0.673170, "height":1.007840}, "confidence":0.935582}
]
}
]
JSON B:
[
{
"frame_id":1,
"filename":"/content/drive/MyDrive/Clocks/clock.jpg",
"class_id":74,
"name":"clock",
"center_x":0.497010,
"center_y":0.561621,
"width":0.300727,
"height":0.557968,
"confidence":0.754266
},
{
"frame_id":2,
"filename":"/content/drive/MyDrive/Clocks/clock2.jpg",
"class_id":74,
"name":"clock",
"center_x":0.651665,
"center_y":0.511030,
"width":0.673170,
"height":1.007840,
"confidence":0.935582
}
]
CodePudding user response:
Assuming there will only ever be one element in objects
you can use dict.pop
and dict.update
data = [{'frame_id': 1, 'filename': '/content/drive/MyDrive/Clocks/clock.jpg', 'objects': [{'class_id': 74, 'name': 'clock', 'relative_coordinates': {'center_x': 0.49701, 'center_y': 0.561621, 'width': 0.300727, 'height': 0.557968}, 'confidence': 0.754266}]},
{'frame_id': 2, 'filename': '/content/drive/MyDrive/Clocks/clock2.jpg', 'objects': [{'class_id': 74, 'name': 'clock', 'relative_coordinates': {'center_x': 0.651665, 'center_y': 0.51103, 'width': 0.67317, 'height': 1.00784}, 'confidence': 0.935582}]}]
result = data.copy()
for d in result:
obj = d.pop('objects')[0]
obj.update(obj.pop('relative_coordinates'))
d.update(obj)
{'center_x': 0.49701,
'center_y': 0.561621,
'class_id': 74,
'confidence': 0.754266,
'filename': '/content/drive/MyDrive/Clocks/clock.jpg',
'frame_id': 1,
'height': 0.557968,
'name': 'clock',
'width': 0.300727},
{'center_x': 0.651665,
'center_y': 0.51103,
'class_id': 74,
'confidence': 0.935582,
'filename': '/content/drive/MyDrive/Clocks/clock2.jpg',
'frame_id': 2,
'height': 1.00784,
'name': 'clock',
'width': 0.67317}]
CodePudding user response:
A recursive function could also be used for this:
from pprint import pprint
data = [
{
"frame_id": 1,
"filename": "/content/drive/MyDrive/Clocks/clock.jpg",
"objects": [
{"class_id": 74, "name": "clock",
"relative_coordinates": {"center_x": 0.497010, "center_y": 0.561621, "width": 0.300727,
"height": 0.557968}, "confidence": 0.754266}
]
},
{
"frame_id": 2,
"filename": "/content/drive/MyDrive/Clocks/clock2.jpg",
"objects": [
{"class_id": 74, "name": "clock",
"relative_coordinates": {"center_x": 0.651665, "center_y": 0.511030, "width": 0.673170,
"height": 1.007840}, "confidence": 0.935582}
]
}
]
def flatten(x):
if isinstance(x, dict):
new_dict = {}
for k, v in x.items():
if isinstance(v, dict):
new_dict.update(v)
elif isinstance(v, list) and v and isinstance(v[0], dict):
for e in v:
new_dict.update(flatten(e))
else:
new_dict[k] = v
return new_dict
return x
result = [flatten(d) for d in data]
pprint(result)
Output:
[{'center_x': 0.49701,
'center_y': 0.561621,
'class_id': 74,
'confidence': 0.754266,
'filename': '/content/drive/MyDrive/Clocks/clock.jpg',
'frame_id': 1,
'height': 0.557968,
'name': 'clock',
'width': 0.300727},
{'center_x': 0.651665,
'center_y': 0.51103,
'class_id': 74,
'confidence': 0.935582,
'filename': '/content/drive/MyDrive/Clocks/clock2.jpg',
'frame_id': 2,
'height': 1.00784,
'name': 'clock',
'width': 0.67317}]
Alternatively, if you're on Python 3.9 you can replace all occurrences of:
new_dict.update(v)
with the dict
union operator:
new_dict |= v