在嵌套JSON中跳过某级并转为Pandas数据框
我有一些结构化的json数据,想把它转成一个数据表:
{
"data": {
"1": {
"Conversion": {
"id": "1",
"datetime": "2024-03-26 08:30:00"
}
},
"50": {
"Conversion": {
"id": "50",
"datetime": "2024-03-27 09:00:00"
}
}
}
}
我通常的方法是用json_normalize,像这样:
df = pd.json_normalize(input['data'])
我的目标是得到一个只包含“id”和“datetime”这两列的表格/数据框。
我想知道怎么跳过数据下面的编号层级,直接到“Conversion”那里。我想象中的写法是这样的(但显然不行):
df = pd.json_normalize(input['data'][*]['Conversion'])
有什么好的方法可以实现这个吗?任何提示都非常感谢!
2 个回答
3
你可以自己整理输入的数据,使用一种叫做列表推导式的方法,像这样:
pd.json_normalize([v['Conversion'] for v in input['data'].values()])
3
你需要手动修改双重列表推导中的数据:
L = [b['Conversion'] for k, v in input['data'].items() for a, b in v.items()]
print (L)
[{'id': '1', 'datetime': '2024-03-26 08:30:00'},
{'id': '50', 'datetime': '2024-03-27 09:00:00'}]
out = pd.json_normalize(L)
print (out)
id datetime
0 1 2024-03-26 08:30:00
1 50 2024-03-27 09:00:00
这里有一个不需要用到 json_normalize
的有效 DataFrame
构造方法:
out = pd.DataFrame(L)
print (out)
id datetime
0 1 2024-03-26 08:30:00
1 50 2024-03-27 09:00:00
感谢 chepner 提供的另一个思路,使用 .values
:
out = pd.json_normalize((b['Conversion'] for v in input['data'].values()
for b in v.values()))
print (out)
id datetime
0 1 2024-03-26 08:30:00
1 50 2024-03-27 09:00:00
out = pd.DataFrame((b['Conversion'] for v in input['data'].values()
for b in v.values()))
print (out)
id datetime
0 1 2024-03-26 08:30:00
1 50 2024-03-27 09:00:00
在 json_normalize
中有一个参数 max_level
,但它的工作方式不同:
最大层级数(字典的深度)以进行标准化。如果设置为 None,则会标准化所有层级。
out = pd.json_normalize(input['data'], max_level=1)
print (out)
data.1 \
0 {'Conversion': {'id': '1', 'datetime': '2024-0...
data.50
0 {'Conversion': {'id': '50', 'datetime': '2024-...
out = pd.json_normalize(input['data'], max_level=2)
print (out)
data.1.Conversion \
0 {'id': '1', 'datetime': '2024-03-26 08:30:00'}
data.50.Conversion
0 {'id': '50', 'datetime': '2024-03-27 09:00:00'}
out = pd.json_normalize(input['data'], max_level=3)
print (out)
data.1.Conversion.id data.1.Conversion.datetime data.50.Conversion.id \
0 1 2024-03-26 08:30:00 50
data.50.Conversion.datetime
0 2024-03-27 09:00:00