You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Met Office Data Point的JSON天气数据读取到Pandas DataFrame中

如何将Met Office Data Point的JSON天气数据读取到Pandas DataFrame中

嘿,我之前刚好处理过Met Office Data Point的天气数据,这种嵌套的JSON结构确实有点让人头大,我来一步步带你把它转成清爽的Pandas DataFrame,包你一看就会!

第一步:先搞懂JSON的层级结构

首先得摸清楚这个JSON的套路:

  • 最外层是SiteRep,里面Wx下的Param是所有天气参数的定义(比如Dm对应“日间最高气温”,单位是℃)
  • 真正的天气数据在DV→Location里,每个Location是一个站点,包含站点ID、名称、经纬度
  • 每个站点下的Period是预报时段(比如按天划分),每个Period里的Rep就是具体的天气数据条目,里面是参数代码和对应的值

第二步:加载JSON数据

先把JSON数据加载到Python里,不管是从本地文件读,还是直接从API请求返回的内容解析,都很简单:

import json
import pandas as pd

# 情况1:从本地JSON文件加载
with open('met_office_weather.json', 'r', encoding='utf-8') as f:
    data = json.load(f)

# 情况2:直接从API请求获取(用requests库)
# import requests
# api_key = "你的Data Point API密钥"
# target_site_id = "你要查的站点ID"
# response = requests.get(f"http://datapoint.metoffice.gov.uk/public/data/val/wxfcs/all/json/{target_site_id}?res=3hourly&key={api_key}")
# data = response.json()

第三步:预处理参数映射

为了让DataFrame的列名更友好,先把参数代码(比如Dm)转成对应的描述,顺便带上单位:

# 提取参数定义,建立代码到描述、单位的映射
param_list = data['SiteRep']['Wx']['Param']
param_name_map = {p['name']: p['$'] for p in param_list}
param_unit_map = {p['name']: p['units'] for p in param_list}

第四步:拆平嵌套数据

这是最关键的一步——把嵌套的JSON数据拆成一行一行的扁平记录,方便转成DataFrame:

weather_records = []

# 遍历每个站点
for location in data['SiteRep']['DV']['Location']:
    # 提取站点基础信息
    site_info = {
        '站点ID': location['i'],
        '站点名称': location['name'],
        '纬度': float(location['lat']),
        '经度': float(location['lon'])
    }
    # 遍历每个预报时段(比如每天)
    for period in location['Period']:
        period_date = period['value']  # 时段的日期
        # 遍历该时段内的每一条天气记录
        for rep in period['Rep']:
            # 先复制站点和日期信息
            record = site_info.copy()
            record['预报日期'] = period_date
            # Rep里的$字段是时段偏移(比如360代表从时段开始过了360分钟,也就是6小时)
            record['时段偏移(分钟)'] = rep.get('$', 0)
            # 遍历每条记录里的天气参数
            for param_code, value in rep.items():
                if param_code == '$':
                    continue  # 跳过时段偏移字段
                # 生成友好的列名,比如"日间最高气温 (℃)"
                column_name = f"{param_name_map[param_code]} ({param_unit_map[param_code]})"
                # 把数值转成float,方便后续分析
                record[column_name] = float(value)
            weather_records.append(record)

第五步:转成Pandas DataFrame

最后一步,把整理好的记录列表转成DataFrame,还可以调整列的顺序让它更直观:

df = pd.DataFrame(weather_records)

# 调整列的顺序,把基础信息放在前面
base_cols = ['站点ID', '站点名称', '纬度', '经度', '预报日期', '时段偏移(分钟)']
weather_cols = [col for col in df.columns if col not in base_cols]
df = df[base_cols + weather_cols]

# 看看结果
print(df.head())

小技巧:优化时段显示

如果觉得时段偏移(分钟)不够直观,可以把它转成小时数,或者直接转成具体的时间:

# 把分钟转成小时
df['时段偏移(小时)'] = df['时段偏移(分钟)'].apply(lambda x: int(x) / 60)
# 或者根据预报日期+偏移计算具体时间
df['预报时间'] = pd.to_datetime(df['预报日期']) + pd.to_timedelta(df['时段偏移(分钟)'], unit='m')

这样处理完,你就得到了一个结构清晰、字段友好的Pandas DataFrame,不管是做分析还是可视化都很方便!

备注:内容来源于stack exchange,提问作者alecjcook

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.16 09:59:34