Использовать json_normalize с посторонним слоем словаря с одним ключом?Python

Программы на Python
Anonymous
Использовать json_normalize с посторонним слоем словаря с одним ключом?

Сообщение Anonymous »

У меня есть данные автоматизированной системы идентификации (AIS) в виде вложенных словарей в кадре данных pandas. Вот пример:
dfAIS
Out[18]:
Message ... MetaData
0 {'ShipStaticData': {'AisVersion': 1, 'CallSign... ... {'MMSI': 255814000, 'MMSI_String': 255814000, ...
1 {'MultiSlotBinaryMessage': {'ApplicationID': {... ... {'MMSI': 2276003, 'MMSI_String': 2276003, 'Shi...
2 {'StandardClassBPositionReport': {'AssignedMod... ... {'MMSI': 503760500, 'MMSI_String': 503760500, ...
3 {'PositionReport': {'Cog': 25.2, 'Communicatio... ... {'MMSI': 211648000, 'MMSI_String': 211648000, ...
4 {'StaticDataReport': {'MessageID': 24, 'PartNu... ... {'MMSI': 338467989, 'MMSI_String': 338467989, ...
... ... ...
139625 {'PositionReport': {'Cog': 360, 'Communication... ... {'MMSI': 244730300, 'MMSI_String': 244730300, ...
139626 {'PositionReport': {'Cog': 231.5, 'Communicati... ... {'MMSI': 219025528, 'MMSI_String': 219025528, ...
139627 {'PositionReport': {'Cog': 360, 'Communication... ... {'MMSI': 273252100, 'MMSI_String': 273252100, ...
139628 {'UnknownMessage': {}} ... {'MMSI': 244730043, 'MMSI_String': 244730043, ...
139629 {'ShipStaticData': {'AisVersion': 1, 'CallSign... ... {'MMSI': 211666470, 'MMSI_String': 211666470, ...

[139630 rows x 3 columns]

Основные данные находятся в столбце «Сообщение». Каждый элемент в нем представляет собой словарь только с 1 ключом и 1 значением. Как показано выше, одним из ключей может быть «ShipStaticData», «MultiSlotBinaryMessage» и т. д., которые мы можем рассматривать как типы сообщений. Назовем этот словарь словарем уровня 1.
Словарь уровня 1 представляет собой внешний уровень отображения, поскольку нужные данные находятся в соответствующем значении, которое само по себе является целым словарем. Назовем последний словарем уровня 2. Как показано выше, поля в словаре уровня 2 могут быть «AisVersion», «ApplicationID», «Cog» и т. д. Здесь указаны допустимые поля.
Я не знаю. нужен ключ для словаря уровня 1, поскольку словарь уровня 2 содержит поле MesssageID, которое гораздо менее двусмысленно сопоставляется с типом сообщения. Кроме того, в кадре данных dfAIS также есть столбец MessageType, не показанный выше, который содержит ту же метку, что и единственный ключ в словаре уровня 1.
Я изучал эту тему манипуляции с кадрами данных с использованием apply для извлечения MessageID из словаря уровня 2. Я также обнаружил, что json_normalize — отличный вариант. К сожалению, во вложенных словарях требуется, чтобы иерархический путь к общим полям имел одинаковые компоненты пути. Я не могу использовать его для описанного выше сценария, поскольку путь Message.ShipStaticData.MessageID отличается от пути Message.MultiSlotBinaryMessage.MessageID. В обоих этих путях второй из трех компонентов пути — это посторонний слой сопоставления, которого я бы не хотел.
Как я могу отменить вложение вложенный словарь, чтобы я мог получить доступ к полю MessageID?
Я пытался использовать pandas.DataFrame.apply, чтобы применить метод словаря items() к элементам столбца dfAIS Сообщение. Он дает серию вложенных кортежей, и
ключ типа постороннего сообщения все еще присутствует:
df = dfAIS.Message.apply(dict.items)

0 ((ShipStaticData, {'AisVersion': 1, 'CallSign'...
1 ((MultiSlotBinaryMessage, {'ApplicationID': {'...
2 ((StandardClassBPositionReport, {'AssignedMode...
3 ((PositionReport, {'Cog': 25.2, 'Communication...
4 ((StaticDataReport, {'MessageID': 24, 'PartNum...

139625 ((PositionReport, {'Cog': 360, 'CommunicationS...
139626 ((PositionReport, {'Cog': 231.5, 'Communicatio...
139627 ((PositionReport, {'Cog': 360, 'CommunicationS...
139628 ((UnknownMessage, {}))
139629 ((ShipStaticData, {'AisVersion': 1, 'CallSign'...
Name: Message, Length: 139630, dtype: object

P.S. Я также ломал голову над тем, как обращаться к меткам «ShipStaticData», «MultiSlotBinaryMessage» и т. д. Это ключи словаря уровня 1. . Было бы удобно говорить о «значении», принимаемом ключом уровня 1, но «значение» уже относится к объекту, на который отображается ключ. Мы можем очень осторожно сказать, что последнее — это значение, связанное с ключом или для ключа, но это все равно вызывает путаницу. Есть ли более ясный (и краткий) способ сослаться на «ShipStaticData», «MultiSlotBinaryMessage» и т. д.?
P.P.S. Хотя вопрос начинается с фрейма данных, вот трехстрочный образец исходного файла jsonl для облегчения ответов, которые могут начинаться с приема файла данных:
{"Message": {"ShipStaticData": {"AisVersion": 0, "CallSign": "GDNB ", "Destination": "AVONMOUTH DREDGING ", "Dimension": {"A": 30, "B": 5, "C": 7, "D": 3}, "Dte": false, "Eta": {"Day": 0, "Hour": 24, "Minute": 60, "Month": 0}, "FixType": 1, "ImoNumber": 702864, "MaximumStaticDraught": 14, "MessageID": 5, "Name": "MALAGO ", "RepeatIndicator": 0, "Spare": false, "Type": 33, "UserID": 235065329, "Valid": true}}, "MessageType": "ShipStaticData", "MetaData": {"MMSI": 235065329, "MMSI_String": 235065329, "ShipName": "MALAGO ", "latitude": 51.50296166666667, "longitude": -2.707621666666667, "time_utc": "2024-04-15 23:00:24.874950587 +0000 UTC"}}
{"Message": {"PositionReport": {"Cog": 226.1, "CommunicationState": 59916, "Latitude": 33.74614666666667, "Longitude": -118.22303833333334, "MessageID": 1, "NavigationalStatus": 0, "PositionAccuracy": false, "Raim": false, "RateOfTurn": 0, "RepeatIndicator": 0, "Sog": 1.1, "Spare": 0, "SpecialManoeuvreIndicator": 0, "Timestamp": 24, "TrueHeading": 11, "UserID": 367693690, "Valid": true}}, "MessageType": "PositionReport", "MetaData": {"MMSI": 367693690, "MMSI_String": 367693690, "ShipName": "KELLY C ", "latitude": 33.74614666666667, "longitude": -118.22303833333334, "time_utc": "2024-04-15 23:00:24.875182234 +0000 UTC"}}
{"Message": {"Interrogation": {"MessageID": 15, "RepeatIndicator": 3, "Spare": 0, "Station1Msg1": {"MessageID": 316004037, "SlotOffset": 0, "StationID": 316004037, "Valid": true}, "Station1Msg2": {"MessageID": 0, "SlotOffset": 0, "Spare": 0, "Valid": false}, "Station2": {"MessageID": 0, "SlotOffset": 0, "Spare1": 0, "Spare2": 0, "StationID": 0, "Valid": false}, "UserID": 3669987, "Valid": true}}, "MessageType": "Interrogation", "MetaData": {"MMSI": 3669987, "MMSI_String": 3669987, "ShipName": "", "latitude": 47.548895, "longitude": -122.78526333333333, "time_utc": "2024-04-15 23:00:24.875383071 +0000 UTC"}}


Подробнее здесь: https://stackoverflow.com/questions/784 ... single-key

Вернуться в «Python»