Как сформировать вложенный json из структуры?

Я читаю бинарный файл большого размера следующим образом:
import struct

filepath = 'hits.dat'

with open(filepath, 'rb') as fp:
    while True:
        bytes = fp.read(28)
        if not bytes or len(bytes) != 28:
            break
        
        event_id, track_id, x, y, z = struct.unpack(">HHddd", bytes)


В результате получается структура следующего вида:
event_id: 256
track_id: 0
x: -7.942855253805373e-275
y: 6.303619193466582e-17
z: 8.500503648212859e-45


Таких структур очень много. Для удобства я бы хотел представить это всё в виде JSON, чтобы каждому event_id соответствовал track_id, а для track_id были свои координаты x, y, z.

Например:
events = {
    'event_id': 1,
    'tracks' : [{
        'track_id': 1,
        'coordinates': [{
            'x':1,
            'y':2,
            'z':3
        },
        {
            'x':4,
            'y':5,
            'z':6
        }]
    }]
}


Как я могу сделать такое с использованием вложенных словарей?
  • Вопрос задан
  • 1040 просмотров
Пригласить эксперта
Ответы на вопрос 1
trapwalker
@trapwalker Куратор тега Python
Программист, энтузиаст
Если событий у вас действительно много, то рекомендую вам не пихать их в один JSON, а воспользоваться вот таким форматом: jsonlines.org
Это разделённые абзацами строки с JSON'ами.
Этот формат не требуют огромного количества памяти (на весь датасет разом), его можно обрабатывать потоково.
Но в задаче не сказано, что отдельные треки одного событий идут подряд и отдельные координаты одного трека тоже идут подряд. Поэтому рассчитывать на это не приходится.
Уточните задачу и можно будет оптимизировать решение по памяти перейдя к потоковой выдаче.
import struct
import json

filepath = 'hits.dat'
events = {}
with open(filepath, 'rb') as fp:
    buffer = fp.read(28)
    while len(buffer) == 28:
        event_id, track_id, x, y, z = struct.unpack(">HHddd", buffer)
        buffer = fp.read(28)

        event = events.setdefault(event_id, dict(event_id=event_id, tracks={}))        
        track = event['tracks'].setdefault(track_id, dict(coordinates=[]))
        track['coordinates'].append(dict(x=x, y=y, z=z))

with open('hits.json', 'w') as fp:
    json.dump(events, fp, indent=2)

Файла у меня вашего нет, поэтому писал на ощупь. Проверяйте.
У вас, кстати, ошибка в примере JSON'а.
Нужно так:
events = {
    1: {
        'event_id': 1,
        'tracks': {
            1: {        
                'track_id': 1,
                'coordinates': [
                    {'x': 1, 'y': 2, 'z': 3},
                    {'x': 4, 'y': 5, 'z': 6}
                ]
            },
            2: {
                'track_id': 2,
                'coordinates': [
                    {'x': 12, 'y': 22, 'z': 33},
                    {'x': 44, 'y': 55, 'z': 66}
                ]
            }

        }
    }
}
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы