【问题标题】:How to handle dynamic schema of JSON objects in Python Pandas如何在 Python Pandas 中处理 JSON 对象的动态模式
【发布时间】:2020-04-08 15:50:15
【问题描述】:

我有一个要使用的 kafka 流,其中包含一些 JSON 格式的信息。

我需要将该 json 数据转换为 Pandas 数据框,以进一步将其输入数据仓库。

问题在于 json 数据结构会根据事件类型不断变化。

例子:

第一个事件的结构如下:

{
    "organization": "nation1",
    "job_id": 1,
    "job_name": "job1",
    "state": {
        "started": "no"
    },
    "timetamp": 1570357814930
}

然后另一个事件以这种结构出现:

{
    "organization": "nation1",
    "job_id": 1,
    "job_name": "job1",
    "state": {
        "started": "yes",
        "attended": "yes"
    },
    "timetamp": 1570357814988
}

注意上面 state 对象的变化。

假设最低级别的结构/层次结构不会改变,即; state 对象最多可以有 startedattended 键值对,但不能更多。虽然从第一个事件中可以看出,state 对象只有 started

对于这种情况,我如何确保获得如下所示的 pandas 数据框。请记住,实际的 json 将有许多这样的字段/映射,它们将具有这样的动态结构

【问题讨论】:

标签: python json pandas schema


【解决方案1】:

正如@Chris A 建议的那样,我认为可以使用json_normalize 解决。 试试这些。

import json
from pandas.io.json import json_normalize

data = '''
[{
    "organization": "nation1",
    "job_id": 1,
    "job_name": "job1",
    "state": {
        "started": "no"
    },
    "timetamp": 1570357814930
},
{
    "organization": "nation1",
    "job_id": 1,
    "job_name": "job1",
    "state": {
        "started": "yes",
        "attended": "yes"
    },
    "timetamp": 1570357814988
}]
'''

json_normalize(json.loads(data))

它为您提供以下数据框

    organization    job_id  job_name    timetamp    state.started   state.attended
0   nation1     1   job1    1570357814930   no  NaN
1   nation1     1   job1    1570357814988   yes     yes

添加不存在的列

data = '''
{
    "organization": "nation1",
    "job_id": 1,
    "job_name": "job1",
    "state": {
        "started": "no"
    },
    "timetamp": 1570357814930
}
'''
df = json_normalize(json.loads(data))
expected_columns = {'state.started', 'state.attended'}
for column in expected_columns - set(df.columns):
    df[column] = 'null'
df

【讨论】:

  • 如果完整结构(所有列)在 1 个 json 文件中的任何一个 json 消息中都可用,这将起作用。例如 event-2 在我的例子中包含所有应该进入的列。但由于我使用 kafka 获取它,我将独立获取这些事件。所以我会得到第一个json,我必须把它读入pandas,然后第二个会在一段时间后进来。我能想到的一种选择是定义所有可能进入的列,然后将传入的消息转储到 pandas DF 中?
  • 在这种情况下,您可以使用默认值 null 添加当前 df 中不存在的列。我会用这个变化更新我的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-24
  • 1970-01-01
  • 1970-01-01
  • 2022-08-18
相关资源
最近更新 更多