首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >数据获取 | ECMWF教你如何下载 ECMWF 实时预报数据

数据获取 | ECMWF教你如何下载 ECMWF 实时预报数据

作者头像
用户11172986
发布2026-06-09 20:19:34
发布2026-06-09 20:19:34
160
举报
文章被收录于专栏:气python风雨气python风雨

数据获取 | ECMWF教你如何下载 ECMWF 实时预报数据

近期因师弟师妹抱怨下数据太慢,我搜索一通发现了这个库,虽然说并不是再分析场数据下载,但预报场估计也是大有需求,于是写了这篇教程

ecmwf-opendata 是由 ECMWF(欧洲中期天气预报中心)官方维护的 Python 包,用于简化从 ECMWF Open Data 实时下载全球数值预报数据。

核心特点

  • 免注册、免 API Key:直接从 ECMWF 官方或云厂商(AWS / Google Cloud / Azure)拉取公开数据
  • 接口与 MARS 一致:使用 ECMWF 的 MARS 请求语言风格选取气象要素,习惯 ecmwf-api-client 的用户零门槛迁移
  • 按需子集下载:通过 paramleveliststep 等参数只下载需要的部分,避免整文件 726 GiB/天的全量传输
  • 多模型支持:IFS(物理驱动)、AIFS-Single(数据驱动单成员)、AIFS-ENS(数据驱动集合预报)

数据来源:ECMWF Open Data 采用 CC BY 4.0 许可。

IFS 和 AIFS 都能拉。

1. 安装

代码语言:javascript
复制
!pip install ecmwf-opendata  -i https://pypi.mirrors.ustc.edu.cn/simple/

代码语言:javascript
复制
Looking in indexes: https://pypi.mirrors.ustc.edu.cn/simple/
Collecting ecmwf-opendata
  Downloading https://mirrors.ustc.edu.cn/pypi/packages/6a/2a/b2a925b4e2830901f6e9064b90892eb3aba4b4ca8564bbaa5acc18666727/ecmwf_opendata-0.3.29-py3-none-any.whl (22 kB)
Collecting multiurl>=0.2.1 (from ecmwf-opendata)
  Downloading https://mirrors.ustc.edu.cn/pypi/packages/93/cf/be4e93afbfa0def2cd6fac9302071db0bd6d0617999ecbf53f92b9398de3/multiurl-0.3.7-py3-none-any.whl (21 kB)
Requirement already satisfied: requests in /opt/conda/lib/python3.11/site-packages (from multiurl>=0.2.1->ecmwf-opendata) (2.32.3)
Requirement already satisfied: tqdm in /opt/conda/lib/python3.11/site-packages (from multiurl>=0.2.1->ecmwf-opendata) (4.67.0)
Requirement already satisfied: pytz in /opt/conda/lib/python3.11/site-packages (from multiurl>=0.2.1->ecmwf-opendata) (2024.1)
Requirement already satisfied: python-dateutil in /opt/conda/lib/python3.11/site-packages (from multiurl>=0.2.1->ecmwf-opendata) (2.9.0.post0)
Requirement already satisfied: six>=1.5 in /opt/conda/lib/python3.11/site-packages (from python-dateutil->multiurl>=0.2.1->ecmwf-opendata) (1.17.0)
Requirement already satisfied: charset-normalizer<4,>=2 in /opt/conda/lib/python3.11/site-packages (from requests->multiurl>=0.2.1->ecmwf-opendata) (3.4.0)
Requirement already satisfied: idna<4,>=2.5 in /opt/conda/lib/python3.11/site-packages (from requests->multiurl>=0.2.1->ecmwf-opendata) (3.10)
Requirement already satisfied: urllib3<3,>=1.21.1 in /opt/conda/lib/python3.11/site-packages (from requests->multiurl>=0.2.1->ecmwf-opendata) (2.2.3)
Requirement already satisfied: certifi>=2017.4.17 in /opt/conda/lib/python3.11/site-packages (from requests->multiurl>=0.2.1->ecmwf-opendata) (2024.12.14)
Installing collected packages: multiurl, ecmwf-opendata
Successfully installed ecmwf-opendata-0.3.29 multiurl-0.3.7

2. Client 初始化与数据源

Client 是唯一的入口类,构造时可指定数据来源、模型和分辨率等。

参数

默认值

说明

source

"ecmwf"

数据源:ecmwf(官方)、aws(亚马逊云)、google(谷歌云)、azure(微软云)

model

"ifs"

模型:ifs(物理驱动)、aifs-single(数据驱动单成员)、aifs-ens(数据驱动集合)

resol

"0p25"

分辨率,目前仅支持 0.25°(约 25 km)

preserve_request_order

False

是否按请求顺序写入字段;设为 True 会增加服务端负载,建议仅在字段较少时使用

infer_stream_keyword

True

是否自动推断 stream(预报系统)参数

提示source="ecmwf" 有 500 个并发连接限制,如遇下载困难可切换到 aws / google / azure

3. 三行代码拉数据

代码语言:javascript
复制
from ecmwf.opendata import Client

client = Client(source="aws")
client.retrieve(
    type="fc",
    param="msl",
    step=24,
    target="data.grib2",
)
代码语言:javascript
复制
20260603180000-24h-oper-fc.grib2:   0%|          | 0.00/515k [00:00<?, ?B/s]
代码语言:javascript
复制
By downloading data from the ECMWF open data dataset, you agree to the terms: Attribution 4.0 International (CC BY 4.0). Please attribute ECMWF when downloading this data.
代码语言:javascript
复制
<ecmwf.opendata.client.Result at 0x7f4ba55bbbd0>

retrieve() 核心参数速查

参数

是否必填

说明

type

数据类型:fc(预报)、cf(控制预报)、pf(扰动预报)、em(集合平均)、es(集合标准差)、ep(概率产品)、tf(热带气旋路径)

param

气象参数,如 msl、2t、gh、t、u、v 等;不写则下载全部参数

step

预报时效(小时),如 24、[24, 48];不写则下载全部时效

date

起报日期,支持 20220125、'2022-01-25'、datetime 对象;不写默认最新

time

起报时次,支持 0、6、12、18;不写默认最新

levtype

层次类型:sfc(单层面)、pl(等压面);不写自动推断

levelist

等压面层列表,如 500、[500, 850];不写则下载全部层

stream

预报系统:oper(HRES 00/12)、scda(HRES 06/18)、enfo(ENS)、wave(海浪);infer_stream_keyword=True 时自动推断

number

集合成员编号,如 1、[1, 10, 20];不写则下载全部成员

target

本地保存路径(GRIB2 或 BUFR 格式)

retrieve() 返回一个结果对象,可通过 result.datetime 获取实际下载数据的起报时间。

4. 用 cfgrib 读取

代码语言:javascript
复制
import xarray as xr

ds = xr.open_dataset("data.grib2", engine="cfgrib")
print(ds)
代码语言:javascript
复制
<xarray.Dataset> Size: 4MB
Dimensions:     (latitude: 721, longitude: 1440)
Coordinates:
    time        datetime64[ns] 8B ...
    step        timedelta64[ns] 8B ...
    meanSea     float64 8B ...
  * latitude    (latitude) float64 6kB 90.0 89.75 89.5 ... -89.5 -89.75 -90.0
  * longitude   (longitude) float64 12kB -180.0 -179.8 -179.5 ... 179.5 179.8
    valid_time  datetime64[ns] 8B ...
Data variables:
    msl         (latitude, longitude) float32 4MB ...
Attributes:
    GRIB_edition:            2
    GRIB_centre:             ecmf
    GRIB_centreDescription:  European Centre for Medium-Range Weather Forecasts
    GRIB_subCentre:          0
    Conventions:             CF-1.7
    institution:             European Centre for Medium-Range Weather Forecasts
    history:                 2026-06-04T13:26 GRIB to CDM+CF via cfgrib-0.9.1...

4. 多参数、多时效下载

paramleveliststep 都支持传入列表,一次请求即可打包下载多个字段。

代码语言:javascript
复制
client = Client(source="aws")
result = client.retrieve(
    type="fc",
    param=["gh", "t"],
    levelist=[500, 850],
    step=[24, 48],
    target="gh_t_500_850.grib2",
)
print("起报时间:", result.datetime)
代码语言:javascript
复制
<multiple>:   0%|          | 0.00/4.01M [00:00<?, ?B/s]
代码语言:javascript
复制
起报时间: 2026-06-03 18:00:00
代码语言:javascript
复制
ds_multi = xr.open_dataset("gh_t_500_850.grib2", engine="cfgrib")
print(ds_multi)
代码语言:javascript
复制
<xarray.Dataset> Size: 33MB
Dimensions:        (step: 2, isobaricInhPa: 2, latitude: 721, longitude: 1440)
Coordinates:
    time           datetime64[ns] 8B ...
  * step           (step) timedelta64[ns] 16B 1 days 2 days
  * isobaricInhPa  (isobaricInhPa) float64 16B 850.0 500.0
  * latitude       (latitude) float64 6kB 90.0 89.75 89.5 ... -89.5 -89.75 -90.0
  * longitude      (longitude) float64 12kB -180.0 -179.8 -179.5 ... 179.5 179.8
    valid_time     (step) datetime64[ns] 16B ...
Data variables:
    gh             (step, isobaricInhPa, latitude, longitude) float32 17MB ...
    t              (step, isobaricInhPa, latitude, longitude) float32 17MB ...
Attributes:
    GRIB_edition:            2
    GRIB_centre:             ecmf
    GRIB_centreDescription:  European Centre for Medium-Range Weather Forecasts
    GRIB_subCentre:          0
    Conventions:             CF-1.7
    institution:             European Centre for Medium-Range Weather Forecasts
    history:                 2026-06-04T13:30 GRIB to CDM+CF via cfgrib-0.9.1...

常用气象参数速查表

单层面(Surface)

参数

说明

单位

2t

2 米温度

K

msl

海平面气压

Pa

sp

地面气压

Pa

10u

10 米 U 风

m/s

10v

10 米 V 风

m/s

tp

总降水量

m

tcwv

整层可降水量

kg/m²

skt

地表温度

K

等压面(Pressure Levels)

参数

说明

单位

gh

位势高度

gpm

t

温度

K

u

U 风

m/s

v

V 风

m/s

q

比湿

kg/kg

r

相对湿度

%

vo

涡度

s⁻¹

d

散度

s⁻¹

海浪(Waves)

参数

说明

单位

swh

有效波高

m

mwp

平均波周期

s

pp1d

峰值波周期

s

mwd

平均波向

°

5. IFS vs AIFS:模型与预报时效

预报系统

时次

预报时效范围

步长

HRES (IFS)

00, 12

0–144 h

3 h

HRES (IFS)

00, 12

144–240 h

6 h

HRES (IFS)

06, 18

0–90 h

3 h

ENS (IFS)

00, 12

0–144 h

3 h

ENS (IFS)

00, 12

144–360 h

6 h

ENS (IFS)

06, 18

0–144 h

3 h

提示:数据一般在起报后 7–9 小时 才可在 Open Data 中访问,取决于预报系统和时效。

同一个接口,换一个 model 参数即可切换 IFS 与 AIFS。

代码语言:javascript
复制
# IFS
client_ifs = Client(source="aws", model="ifs")
client_ifs.retrieve(
    type="fc", param="msl",
    step=24,
    target="ifs_msl.grib2",
)

# AIFS
client_aifs = Client(source="aws", model="aifs-single")
client_aifs.retrieve(
    type="fc", param="msl",
    step=24,
    target="aifs_msl.grib2",
)
代码语言:javascript
复制
20260603180000-24h-oper-fc.grib2:   0%|          | 0.00/515k [00:00<?, ?B/s]
代码语言:javascript
复制
20260604000000-24h-oper-fc.grib2:   0%|          | 0.00/471k [00:00<?, ?B/s]
代码语言:javascript
复制
<ecmwf.opendata.client.Result at 0x7f4acc9bff90>
代码语言:javascript
复制
import os

ifs_size = os.path.getsize("ifs_msl.grib2")
aifs_size = os.path.getsize("aifs_msl.grib2")
print(f"IFS: {ifs_size / 1024:.1f} KB")
print(f"AIFS: {aifs_size / 1024:.1f} KB")
代码语言:javascript
复制
IFS: 514.8 KB
AIFS: 470.9 KB

7. 实战:画一张 500hPa 形势场

代码语言:javascript
复制
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.feature as cfeature
import numpy as np
import xarray as xr
# # 下载数据
client = Client(source="aws", model="aifs-single")
client.retrieve(type="fc", param="gh", levelist=500, step=24, target="aifs_gh500.grib2")
client.retrieve(type="fc", param="msl", step=24, target="aifs_msl.grib2")

# 读取
gh = xr.open_dataset("aifs_gh500.grib2", engine="cfgrib")["gh"]
msl = xr.open_dataset("aifs_msl.grib2", engine="cfgrib")["msl"]
代码语言:javascript
复制
# 画图
proj = ccrs.PlateCarree(central_longitude=110)
fig, ax = plt.subplots(figsize=(12, 8), subplot_kw={"projection": proj})

ax.set_extent([70, 140, 15, 55], crs=ccrs.PlateCarree())
ax.add_feature(cfeature.COASTLINE, linewidth=0.8)
# ax.add_feature(cfeature.BORDERS, linewidth=0.4, alpha=0.5)

# 位势高度等值线
levels = np.arange(5000, 6000, 40)
cs = ax.contour(
    gh.longitude, gh.latitude, gh.squeeze() / 10,
    levels=levels, colors="black", linewidths=1.0,
    transform=ccrs.PlateCarree(),
)
ax.clabel(cs, inline=True, fontsize=8, fmt="%d")

# 海平面气压填色
msl_hpa = msl.squeeze() / 100
cf = ax.contourf(
    msl.longitude, msl.latitude, msl_hpa,
    levels=np.arange(960, 1050, 5),
    cmap="RdBu_r", alpha=0.4,
    transform=ccrs.PlateCarree(),
)
plt.colorbar(cf, ax=ax, label="MSL (hPa)", shrink=0.7)

ax.set_title(
    "AIFS 500hPa Geopotential + MSL\n"
    f"Init: {gh.time.values.astype('datetime64[h]').tolist()} "
    f"Step: +24h"
)
plt.tight_layout()
plt.savefig("aifs_500hpa_forecast.png", dpi=150)
plt.show()
output
output

output

8. 高级用法

8.1 查询最新可用起报时间(不下载)

Client.latest() 只查询服务器上最新数据的时间,不执行下载,适合在自动化脚本中判断数据是否已上线。

代码语言:javascript
复制
from ecmwf.opendata import Client

client = Client(source="aws")
latest = client.latest(type="fc", param="msl", step=24)
print("最新可用起报时间:", latest)

8.2 整文件下载(跳过子集筛选)

Client.download()retrieve() 参数相同,但会忽略 paramlevelistnumber 等子集参数,直接下载整文件。当你需要下载大部分字段时,整文件下载效率更高。

注意:整天的完整数据约 726 GiB,请谨慎使用。

代码语言:javascript
复制
client = Client(source="aws")
# 仅按 date/time/step/type 定位文件,忽略 param 等子集参数
client.download(
    type="fc",
    step=24,
    target="full_file.grib2",
)

8.3 集合预报(ENS)下载示例

ECMWF 集合预报提供 50 个扰动成员 + 1 个控制成员。使用 stream="enfo"type="pf"(扰动)或 "cf"(控制),并通过 number 指定成员编号。

代码语言:javascript
复制
# 下载控制成员
client = Client(source="aws")
client.retrieve(
    stream="enfo",
    type="cf",
    step=24,
    param="msl",
    target="ens_cf_msl.grib2",
)

# 下载第 1、3、5… 奇数成员
client.retrieve(
    stream="enfo",
    type="pf",
    step=24,
    param="msl",
    number=[num for num in range(1, 51, 2)],
    target="ens_pf_msl.grib2",
)

8.4 用字典方式传入请求

retrieve() 也支持将请求打包为字典传入,方便在配置文件中管理下载任务。

代码语言:javascript
复制
client = Client(source="aws")
request = {
    "type": "fc",
    "step": [24, 48, 72],
    "param": ["2t", "msl"],
}
client.retrieve(request, target="dict_request.grib2")

小结

实际体验下来排队倒是不用排,aws源速度挺慢的,也可能有网络差异,

不论如何这也算是ec排队时间过长下的一种选择

参考链接

  • ecmwf-opendata PyPI
  • ECMWF Open Data 官方页面
  • ECMWF MARS 关键字文档
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2026-06-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 气python风雨 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 数据获取 | ECMWF教你如何下载 ECMWF 实时预报数据
    • 核心特点
    • 1. 安装
    • 2. Client 初始化与数据源
    • 3. 三行代码拉数据
      • retrieve() 核心参数速查
    • 4. 用 cfgrib 读取
    • 4. 多参数、多时效下载
      • 常用气象参数速查表
    • 5. IFS vs AIFS:模型与预报时效
    • 7. 实战:画一张 500hPa 形势场
    • 8. 高级用法
      • 8.1 查询最新可用起报时间(不下载)
      • 8.2 整文件下载(跳过子集筛选)
      • 8.3 集合预报(ENS)下载示例
      • 8.4 用字典方式传入请求
    • 小结
    • 参考链接
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档