ERA5 数据下载教程

4月 10, 2026 · 4 分钟阅读时长
blog

ERA5 数据下载教程

使用 CDS API 通过 Python 脚本下载 ECMWF ERA5 再分析气象数据


1. 注册与获取 API Key

1.1 注册账号

访问 Copernicus Climate Data Store 并注册账号。

1.2 获取 API Key

登录后,点击右上角用户图标 → Your profile,页面底部可以看到:

  • Personal Access Token(即 API Key)

1.3 配置本地凭证

在用户主目录下创建 .cdsapirc 文件:

  • Windows: C:\Users\<你的用户名>\.cdsapirc
  • Linux/Mac: ~/.cdsapirc

文件内容:

url: https://cds.climate.copernicus.eu/api
key: <你的Personal Access Token>
重要

key 后面直接填 Token 字符串,不要加引号。


2. 安装依赖

pip install cdsapi

验证安装:

import cdsapi
c = cdsapi.Client()  # 如果没报错,说明配置成功

3. 基础用法

3.1 最简示例

import cdsapi

c = cdsapi.Client()

c.retrieve(
    'reanalysis-era5-single-levels',     # 数据集名称
    {
        'product_type': 'reanalysis',    # 产品类型
        'variable': '2m_temperature',    # 变量
        'year': '2023',                  # 年
        'month': '01',                   # 月
        'day': '01',                     # 日
        'time': '12:00',                 # 时间 (UTC)
        'area': [40, 110, 35, 115],      # 区域 [北, 西, 南, 东]
        'format': 'netcdf',              # 输出格式
    },
    'output.nc'                          # 输出文件名
)

3.2 参数说明

参数说明示例
product_type产品类型'reanalysis'
variable变量名(可多个)['2m_temperature', 'surface_pressure']
year年份(可多个)'2023' 或 ['2022', '2023']
month月份(可多个)'06' 或 [f'{m:02d}' for m in range(1,13)]
day日期(可多个)[f'{d:02d}' for d in range(1,32)]
timeUTC 时间(可多个)'03:00' 或 ['03:00', '04:00', '05:00']
area裁剪区域[北纬, 西经, 南纬, 东经]
format输出格式'netcdf' 或 'grib'

4. 常用变量速查

4.1 单层变量(single-levels)

数据集名:reanalysis-era5-single-levels

API 变量名含义单位
10m_u_component_of_wind10m 东西风分量m/s
10m_v_component_of_wind10m 南北风分量m/s
2m_temperature2m 温度K
surface_pressure地表气压Pa
total_precipitation总降水量m
2m_dewpoint_temperature2m 露点温度K
mean_sea_level_pressure海平面气压Pa
boundary_layer_height边界层高度m
total_cloud_cover总云量0~1

4.2 气压层变量(pressure-levels)

数据集名:reanalysis-era5-pressure-levels

API 变量名含义单位
u_component_of_wind东西风m/s
v_component_of_wind南北风m/s
temperature温度K
geopotential位势m²/s²
relative_humidity相对湿度%
specific_humidity比湿kg/kg

气压层需额外指定 pressure_level 参数:

'pressure_level': ['500', '700', '850', '925', '1000']  # 单位: hPa

5. 实战示例

5.1 下载特定区域的风场数据

import cdsapi

c = cdsapi.Client()

c.retrieve(
    'reanalysis-era5-single-levels',
    {
        'product_type': 'reanalysis',
        'variable': [
            '10m_u_component_of_wind',
            '10m_v_component_of_wind',
            '2m_temperature',
            'surface_pressure',
        ],
        'year': '2024',
        'month': [f'{m:02d}' for m in range(1, 13)],  # 全年
        'day': [f'{d:02d}' for d in range(1, 32)],     # 全月
        'time': ['03:00', '04:00', '05:00'],            # 仅卫星过境时段
        'area': [37, 112, 36, 113],  # 李村矿区
        'format': 'netcdf',
    },
    'era5_2024_wind.nc'
)

5.2 并行下载多年数据

import cdsapi
from concurrent.futures import ThreadPoolExecutor, as_completed

def download_year(year):
    """下载单年数据"""
    output = f'era5_{year}.nc'
    try:
        c = cdsapi.Client()  # 每个线程创建独立客户端
        c.retrieve(
            'reanalysis-era5-single-levels',
            {
                'product_type': 'reanalysis',
                'variable': [
                    '10m_u_component_of_wind',
                    '10m_v_component_of_wind',
                ],
                'year': str(year),
                'month': [f'{m:02d}' for m in range(1, 13)],
                'day': [f'{d:02d}' for d in range(1, 32)],
                'time': ['03:00', '04:00', '05:00'],
                'area': [37, 112, 36, 113],
                'format': 'netcdf',
            },
            output
        )
        return f'[OK] {year}'
    except Exception as e:
        return f'[FAIL] {year}: {e}'

# 最多 4 个并发
with ThreadPoolExecutor(max_workers=4) as executor:
    futures = {executor.submit(download_year, y): y for y in range(2020, 2026)}
    for future in as_completed(futures):
        print(future.result())

5.3 下载后合并多个文件

import xarray as xr

files = ['era5_2020.nc', 'era5_2021.nc', 'era5_2022.nc']
ds = xr.open_mfdataset(files, combine='by_coords')
ds.to_netcdf('era5_2020-2022_merged.nc')
ds.close()
print("合并完成")

5.4 下载气压层数据

import cdsapi

c = cdsapi.Client()

c.retrieve(
    'reanalysis-era5-pressure-levels',  # 注意数据集名不同
    {
        'product_type': 'reanalysis',
        'variable': [
            'u_component_of_wind',
            'v_component_of_wind',
            'temperature',
        ],
        'pressure_level': ['850', '925'],  # 气压层 (hPa)
        'year': '2024',
        'month': '06',
        'day': '15',
        'time': '03:00',
        'area': [37, 112, 36, 113],
        'format': 'netcdf',
    },
    'era5_pressure_levels.nc'
)

6. 注意事项

6.1 请求大小限制

CDS API 对单次请求有大小限制。如果报 403 cost limits exceeded,需要拆分请求:

策略说明
减少时间只下需要的小时(如 03:00-05:00)
拆分年份按年分别提交
缩小区域尽量只覆盖研究区
提示

一般经验:1年 × 3小时 × 小区域 的单层数据可以一次提交。全年 24 小时的通常需要按月或按季度拆分。

6.2 时间说明

  • ERA5 时间均为 UTC
  • 北京时间 = UTC + 8 小时
  • 例:北京时间 11:00 ≈ UTC 03:00

6.3 空间分辨率

  • ERA5 默认分辨率:0.25° × 0.25°(约 25km)
  • area 中的边界会自动对齐到最近的 0.25° 网格

6.4 常见错误

错误原因解决
403 cost limits exceeded请求数据量太大减少时间/拆分年份
ModuleNotFoundError: cdsapi未安装pip install cdsapi
Exception: Missing/malformed configuration.cdsapirc 配置错误检查文件路径和格式
SSLError / ConnectionReset网络不稳定重试,或挂代理

7. 读取下载的数据

import xarray as xr
import numpy as np

ds = xr.open_dataset('era5_2024_wind.nc', engine='netcdf4')

# 查看基本信息
print(ds)
print('变量:', list(ds.data_vars))
print('坐标:', list(ds.coords))

# 提取某时刻某位置的风速
lon, lat = 112.87, 36.09
u = ds['u10'].sel(longitude=lon, latitude=lat, method='nearest')
v = ds['v10'].sel(longitude=lon, latitude=lat, method='nearest')
wind_speed = np.sqrt(u**2 + v**2)

# 风向 (气象标准: 从北顺时针)
wind_dir = (270 - np.degrees(np.arctan2(v, u))) % 360

print(f'风速: {float(wind_speed.isel(valid_time=0)):.2f} m/s')
print(f'风向: {float(wind_dir.isel(valid_time=0)):.1f}°')

ds.close()

8. 参考链接

Townsend
Authors
2025级博士研究生
我是中国矿业大学2025级在读博士生,研究方向为大气甲烷反演与量化。 当前依托碳排放与空气质量遥感团队开展研究,聚焦“遥感反演-排放量化-影响归因”技术链条。