Home > OS >  Reformat json file so it does not contain nested data
Reformat json file so it does not contain nested data

Time:10-22

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
  • Related