如何将JSON中的坐标时序数据转换为Numpy三维网格?
将JSON时序网格数据转换为Numpy三维数组
问题背景
需要把JSON中的时序网格数据转为Numpy三维数组,维度对应时间步 × Y轴网格数 × X轴网格数(可按需调整顺序)。
JSON数据加载方式:
import json with open('json_data.json','r') as openfile: json_object = json.load(openfile)
核心数据说明:
json_object['info']包含网格参数:Numx(X方向单元格数)、Numy(Y方向单元格数)json_object['data']是包含Numx×Numy个字典的列表,每个字典存坐标X/Y,以及Data字段——该字段是时间步列表,每个元素含Time(时间戳)和Value(对应数值),所有坐标的时间戳完全一致。
已尝试的方法
- 用Pandas展开数据,但无法转成三维网格:
import pandas as pd df = pd.json_normalize(json_object["data"], record_path =["Data"],meta=["X","Y"])
- 遍历时间戳生成二维网格,但无法整合为三维结构:
timeStamps = [t['Time'] for t in json_object['data'][0]['Data']] dfTimestamps = {} for i,ts in enumerate(timeStamps): dfTimestamps[ts] = {} X = [] Y = [] vals = [] for d in json_object['data']: X.append(d['X']) Y.append(d['Y']) vals.append(d['Data'][i]['Value']) dfTimestamps[ts]['X'] = X dfTimestamps[ts]['Y'] = Y dfTimestamps[ts]['Value'] = vals
解决方案
方法一:基于Pandas快速转换
利用Pandas的透视表功能快速重塑数据:
import pandas as pd import numpy as np # 1. 展开时序数据到DataFrame df = pd.json_normalize(json_object["data"], record_path=["Data"], meta=["X", "Y"]) # 2. 获取网格参数 num_x = json_object['info']['Numx'] num_y = json_object['info']['Numy'] # 3. 映射实际坐标到网格索引(根据坐标方向调整排序规则) x_coords = sorted(df['X'].unique()) y_coords = sorted(df['Y'].unique(), reverse=True) # Y轴反转适配网格从上到下的顺序 x_map = {x: idx for idx, x in enumerate(x_coords)} y_map = {y: idx for idx, y in enumerate(y_coords)} # 4. 添加网格索引列 df['x_idx'] = df['X'].map(x_map) df['y_idx'] = df['Y'].map(y_map) # 5. 按时间排序并重塑为三维数组 df_sorted = df.sort_values('Time') grid_3d = df_sorted.pivot_table(index='Time', columns=['y_idx', 'x_idx'], values='Value').to_numpy() # 输出形状:(时间步数, Y网格数, X网格数) print(grid_3d.shape)
方法二:纯Numpy+字典映射(无Pandas依赖)
直接操作数组填充数据,适合对依赖包有要求的场景:
import numpy as np # 1. 获取网格和时间参数 num_x = json_object['info']['Numx'] num_y = json_object['info']['Numy'] time_steps = json_object['data'][0]['Data'] num_time = len(time_steps) # 2. 构建坐标到网格索引的映射 x_coords = sorted([d['X'] for d in json_object['data']]) y_coords = sorted([d['Y'] for d in json_object['data']], reverse=True) x_map = {x: i for i, x in enumerate(x_coords)} y_map = {y: j for j, y in enumerate(y_coords)} # 3. 初始化三维数组 grid_3d = np.zeros((num_time, num_y, num_x), dtype=np.float64) # 4. 遍历每个坐标,填充时序数据 for cell in json_object['data']: x_idx = x_map[cell['X']] y_idx = y_map[cell['Y']] for t_idx, time_data in enumerate(cell['Data']): grid_3d[t_idx, y_idx, x_idx] = time_data['Value'] print(grid_3d.shape)
注意事项
- 坐标映射时要确认X/Y的排序方向,若实际Y坐标是从大到小对应网格的顶部到底部,需用
reverse=True避免网格翻转。 - 若存在缺失坐标点,初始化数组时可改用
np.full((num_time, num_y, num_x), np.nan)填充空值,后续再处理缺失数据。 - 可通过
grid_3d.transpose(2,1,0)调整维度顺序为X轴 × Y轴 × 时间步,按需使用。
内容的提问来源于stack exchange,提问作者aloevgaard
相关产品推荐
相关产品推荐

