将 protobuf 提要转换为 pandas 数据帧

Converting protobuf feed to pandas dataframe

我正在尝试将 protobuf 提要隐藏到 pandas 数据框,用于我的一个爱好项目。我尝试了几种不同的技术来实现这一点,但似乎没有什么能真正解决我的问题。

我使用以下代码检索 GTFS-RT TripUpdates 提要:

feed = gtfs_realtime_pb2.FeedMessage()
headers = {
    'Accept': 'application/octet-stream',
    'Accept-encoding': 'br, gzip, deflate'
}

response = requests.get('<PROVIDER:APIKEY>', headers=headers, stream=True)

feed.ParseFromString(response.content)
test_dict = protobuf_to_dict(feed)

使用protobuf_to_dict的结果是一个只有一行的字典:

{'header': {'gtfs_realtime_version': '2.0', 'incrementality': 0, 'timestamp': 1641582104}, 'entity': [{'id': '14050001276385923' [...]

我尝试了几种方法来解决这个问题。

以 JSON 的形式读取提要消息:无效,因为 JSON 对象必须是 str、bytes 或 bytearray,而不是 dict。

迭代字典:

for entity in test_dict.entity:
    if entity.HasField('vehicle')
        [logic for building dataframe]

也没用,因为'dict'对象没有属性'entity'。

好的!经过几个小时的阅读后,我尝试按照 和其他一些线程中的描述对提要消息进行扁平化和规范化。不幸的是,json_normalizeflatten_json 都没有解决问题。

在这一点上,我想绕圈子,看不到可能对我有帮助的非常明显的东西。最终目标是创建一个包含 TripUpdates 数据的数据框,稍后将与另一个数据框合并以更新到达和离开时间。

可以通过使用简单的 for 循环遍历提要消息来解决此问题:

feed = gtfs_realtime_pb2.FeedMessage()
headers = {
    'Accept': 'application/octet-stream',
    'Accept-encoding': 'br, gzip, deflate'
}

response = requests.get('<PROVIDER:APIKEY>', headers=headers, stream=True)

feed.ParseFromString(response.content)

for entity in feed.entity:
    if entity.HasField('trip_update'):
        # Accessing values in feed message
        if entity.trip_update.trip.trip_id == something:
            [add to list]

稍后,列表将转换为 pandas 数据框。