如何将GraphQL查询结果解析为Pandas DataFrame?
问题:解析GraphQL查询结果到Pandas DataFrame
本人主要从事Python GIS相关工作,对JSON语法较为陌生。目前需要将GraphQL查询结果解析为Pandas DataFrame,以便用这些数据更新其他文件。已尝试两天仍未找到正确的解析方法,目标是提取传感器名称、timeUTC字段和finalValue值到表格中。
GraphQL查询示例结果(敏感数据已隐藏)
{"data": {"securityToken": "***********************************","node": {"name": "*****************","locations": {"edges": [{"node": {"name": "VW_01","lastSampleForAllSensorTypes": {"edges": [{"node": {"timeUTC": "2023-02-09T16:30:02.128000Z","finalValue": 3.6}},{"node": {"timeUTC": "2023-02-09T16:30:00.069000Z","finalValue": 16.59}},{"node": {"timeUTC": "2023-02-08T18:30:02.082000Z","finalValue": 0}}]}},{"node": {"name": "Tilt_01","lastSampleForAllSensorTypes": {"edges": [{"node": {"timeUTC": "2023-02-09T16:30:09.202000Z","finalValue": 1.5515986838415172}},{"node": {"timeUTC": "2023-02-09T16:30:09.202000Z","finalValue": -0.04759077784648378}},{"node": {"timeUTC": "2022-08-23T08:30:09.098000Z","finalValue": 48302.57888302765}},{"node": {"timeUTC": "2023-02-09T16:30:09.308000Z","finalValue": 3.593}},{"node": {"timeUTC": "2023-02-09T16:30:00.144000Z","finalValue": 18.97}},{"node": {"timeUTC": "2023-02-09T03:30:09.209000Z","finalValue": 0}},{"node": {"timeUTC": "2023-02-09T16:30:09.202000Z","finalValue": 0.08889998474121086}},{"node": {"timeUTC": "2023-02-09T16:30:09.202000Z","finalValue": -0.003600174713134674}},{"node": {"timeUTC": "2023-02-09T16:30:09.202000Z","finalValue": 88.5111}}]}}}]}}}}
当前使用的代码(无法正常运行)
url = '*************************************' r = requests.post(url, json={'query': query}) print(r.status_code) print(r.text) data = json.loads(r.text) df = pd.json_normalize(data, ['name', 'timeUTC', 'finalValue'])
解决方案
方法1:手动遍历嵌套结构(直观易懂)
先提取核心嵌套数据,再遍历每个传感器及其采样记录,整理成DataFrame所需的行数据:
import requests import pandas as pd import json url = '*************************************' r = requests.post(url, json={'query': query}) data = json.loads(r.text) # 初始化空列表存储行数据 rows = [] # 遍历每个传感器节点 for location_edge in data['data']['node']['locations']['edges']: sensor_name = location_edge['node']['name'] # 获取该传感器的所有采样记录 sample_edges = location_edge['node']['lastSampleForAllSensorTypes']['edges'] for sample_edge in sample_edges: sample_data = sample_edge['node'] rows.append({ '传感器名称': sensor_name, 'timeUTC': sample_data['timeUTC'], 'finalValue': sample_data['finalValue'] }) # 转换为DataFrame df = pd.DataFrame(rows) print(df)
方法2:使用pd.json_normalize(更高效)
利用json_normalize的record_path指定采样数据的嵌套路径,meta指定需要保留的传感器名称元数据:
import requests import pandas as pd import json url = '*************************************' r = requests.post(url, json={'query': query}) data = json.loads(r.text) # 直接解析嵌套JSON df = pd.json_normalize( data['data']['node']['locations']['edges'], # 指定采样数据的路径:每个location下的采样edges数组 record_path=['node', 'lastSampleForAllSensorTypes', 'edges'], # 指定需要提取的传感器名称(元数据) meta=['node', ['node', 'name']], # 元数据列名前缀,避免和采样数据的node字段冲突 meta_prefix='sensor_' ) # 重命名列并筛选需要的字段 df = df.rename(columns={ 'node.timeUTC': 'timeUTC', 'node.finalValue': 'finalValue', 'sensor_node.name': '传感器名称' })[['传感器名称', 'timeUTC', 'finalValue']] print(df)
错误原因说明
你之前的pd.json_normalize用法错误,没有正确指定嵌套数据的路径。原JSON是多层嵌套结构:data -> node -> locations -> edges是传感器列表,每个传感器下的lastSampleForAllSensorTypes -> edges是采样数据数组,必须明确指定record_path指向采样数据的数组位置,同时用meta关联传感器名称。
内容的提问来源于stack exchange,提问作者Matt Luttrell
相关产品推荐
相关产品推荐

