如何将带有嵌套对象的 JSON 文件读取为 pandas DataFrame?
- 2025-02-08 08:52:00
- admin 原创
- 51
问题描述:
我很好奇如何使用 pandas 读取以下结构的嵌套 json:
{
"number": "",
"date": "01.10.2016",
"name": "R 3932",
"locations": [
{
"depTimeDiffMin": "0",
"name": "Spital am Pyhrn Bahnhof",
"arrTime": "",
"depTime": "06:32",
"platform": "2",
"stationIdx": "0",
"arrTimeDiffMin": "",
"track": "R 3932"
},
{
"depTimeDiffMin": "0",
"name": "Windischgarsten Bahnhof",
"arrTime": "06:37",
"depTime": "06:40",
"platform": "2",
"stationIdx": "1",
"arrTimeDiffMin": "1",
"track": ""
},
{
"depTimeDiffMin": "",
"name": "Linz/Donau Hbf",
"arrTime": "08:24",
"depTime": "",
"platform": "1A-B",
"stationIdx": "22",
"arrTimeDiffMin": "1",
"track": ""
}
]
}
此处将数组保留为 json。我更希望将其扩展为列。
pd.read_json("/myJson.json", orient='records')
编辑
感谢第一个回答。我应该完善我的问题:数组中嵌套属性的展平不是强制性的。只需将 [A, B, C] 连接起来即可。
我的文件包含多个 JSON 对象(每行 1 个),我想保留编号、日期、名称和位置列。但是,我需要连接位置。
allLocations = ""
isFirst = True
for location in result.locations:
if isFirst:
isFirst = False
allLocations = location['name']
else:
allLocations += "; " + location['name']
allLocations
我在这里的方法似乎不是高效的/熊猫风格。
解决方案 1:
您可以使用json_normalize
:
import json
with open('myJson.json') as data_file:
data = json.load(data_file)
df = pd.json_normalize(data, 'locations', ['date', 'number', 'name'],
record_prefix='locations_')
print (df)
locations_arrTime locations_arrTimeDiffMin locations_depTime \n0 06:32
1 06:37 1 06:40
2 08:24 1
locations_depTimeDiffMin locations_name locations_platform \n0 0 Spital am Pyhrn Bahnhof 2
1 0 Windischgarsten Bahnhof 2
2 Linz/Donau Hbf 1A-B
locations_stationIdx locations_track number name date
0 0 R 3932 R 3932 01.10.2016
1 1 R 3932 01.10.2016
2 22 R 3932 01.10.2016
编辑:
您可以read_json
通过构造函数解析name
并DataFrame
使用最后groupby
应用join
:
df = pd.read_json("myJson.json")
df.locations = pd.DataFrame(df.locations.values.tolist())['name']
df = df.groupby(['date','name','number'])['locations'].apply(','.join).reset_index()
print (df)
date name number locations
0 2016-01-10 R 3932 Spital am Pyhrn Bahnhof,Windischgarsten Bahnho...
解决方案 2:
如果有人发现这个,还有另一种选择,因为我正在通过笔记本工作。使用 df 读取文件
df = pd.read_json('filename.json')
df2 = pd.DataFrame.from_records(df['nest_level_1']['nest_level_2'])
快乐编码
解决方案 3:
一种可能的替代方法pandas.json_normalize
是通过从嵌套字典中仅提取选定的键和值来构建自己的数据框。这样做的主要原因是因为 json_normalize 对于非常大的 json 文件会变得很慢(并且可能并不总是产生您想要的输出)。
因此,这里有另一种方法可以使用来展平 pandas 中的嵌套字典glom
。目的是从嵌套字典中提取选定的键和值,并将它们保存在 pandas 数据框的单独列中(:
以下是分步指南: https: //medium.com/@enrico.alemani/flatten-nested-dictionaries-in-pandas-using-glom-7948345c88f5
import pandas as pd
from glom import glom
from ast import literal_eval
target = {
"number": "",
"date": "01.10.2016",
"name": "R 3932",
"locations":
{
"depTimeDiffMin": "0",
"name": "Spital am Pyhrn Bahnhof",
"arrTime": "",
"depTime": "06:32",
"platform": "2",
"stationIdx": "0",
"arrTimeDiffMin": "",
"track": "R 3932"
}
}
# Import data
df = pd.DataFrame([str(target)], columns=['target'])
# Extract id keys and save value into a separate pandas column
df['id'] = df['target'].apply(lambda row: glom(literal_eval(row), 'locations.name'))
解决方案 4:
我有一个多行 Json,每行都有一个 json 对象 {'a':'b','scope':{'eid':123213}} {'a':'d','scope':{'eid':1343213}}
不用逗号分隔。每行都是独立的
我使用以下逻辑来读取嵌套结构
阈值 = pd.read_json(r“/content/data.json”,lines=True)
threshold = pd.read_json(r"/content/data.json",lines=True)
threshold['entityId'] = pd.DataFrame.from_records(threshold['scope'])['entityId']
threshold.head()