ERA5-Land数据高效下载与处理实战指南:从CDS API配置到Python脚本编写
2026/6/26 3:25:09 网站建设 项目流程

1. 项目概述:从“数据饥渴”到“精准投喂”

做气象、水文、生态或者农业模型的朋友,对ERA5-Land这个名字一定不陌生。它就像是欧洲中期天气预报中心(ECMWF)为我们这些搞地学研究的人开的一个“数据自助餐厅”,里面摆满了从1950年至今、覆盖全球、时间分辨率最高到小时级、空间分辨率高达9公里的地表再分析数据“硬菜”。温度、降水、土壤湿度、辐射、蒸散发……你能想到的绝大多数地表关键变量,这里几乎都有。但问题来了,这个餐厅的“取餐流程”对新手来说,有点像进了米其林后厨——工具专业、步骤繁多,一不小心就容易“点错菜”或者“下错单”,最后要么等半天没动静,要么下载下来一堆用不了的数据。

我自己在项目初期就踩过不少坑:兴冲冲地选了一大片区域和几十个变量,结果API返回一个错误说请求超载;或者好不容易下载下来一个几十G的NetCDF文件,用Panoply打开一看,时间维度是乱的,还得自己写脚本重排。更常见的是,面对CDS(气候变化数据存储)网站上那密密麻麻的参数列表和复杂的检索语法,感觉无从下手。所以,今天我就结合自己多次“实战”的经验,抛开那些官方的、冗长的教程,直接给你梳理一套从零开始、高效下载ERA5-Land数据的“保姆级”操作流。我们的目标很明确:让你用最少的步骤,拿到最干净、可直接用于分析的数据。

2. 核心需求解析:你到底需要什么样的数据?

在动手敲代码之前,花十分钟想清楚你的需求,能省下后面十个小时的调试和数据处理时间。ERA5-Land数据体量巨大,盲目下载只会带来存储灾难和时间浪费。

2.1 明确时空范围和变量

这是最关键的一步。你需要问自己四个问题:

  1. 时间范围:你需要哪一段时期的数据?是某个具体的年份,还是连续的多年序列?时间分辨率要多大?是逐小时、逐日还是逐月平均?对于长期趋势分析,月平均数据通常就够了,文件量会小很多;如果研究日变化或极端事件,就必须用小时数据。
  2. 空间范围:你的研究区在哪里?是一个点(如某个气象站)、一个区域(如某个流域),还是全球?ERA5-Land采用规则的经纬度网格(0.1° x 0.1°,约9公里),你需要用经纬度边界(North, West, South, East)来框定它。注意:这里的“西”和“东”是经度,西经为负,东经为正;“北”和“南”是纬度,北纬为正,南纬为负。例如,中国的范围大致是[55, 70, 15, 140](北纬55度到15度,东经70度到140度)。建议先用GIS软件或在线地图确认一下边界,避免下错。
  3. 所需变量:ERA5-Land有超过50个变量。你真正需要的是哪几个?去CDS的 ERA5-Land数据目录 仔细查看变量列表和单位。常见的比如:
    • 2m_temperature:2米高度气温。
    • total_precipitation:总降水量(注意是累积量,小时数据是前一小时内的累积)。
    • surface_solar_radiation_downwards:地表太阳辐射下行。
    • volumetric_soil_water_layer_1:第一层(0-7cm)土壤体积含水量。
    • evaporation_from_vegetation_transpiration:植被蒸腾。
  4. 数据格式:通常我们选择NetCDF格式,这是地球科学领域的标准格式,可以被绝大多数软件(如Python的xarray, NCL, Panoply, ArcGIS)直接读取。

注意:ERA5-Land的数据有“再分析”性质,它是利用模型同化了大量观测数据得到的,在空间连续性和物理一致性上非常出色,但并非直接的站点观测。在站点稀疏的地区,其精度需要谨慎评估。

2.2 选择下载工具与策略

主要有三种方式,各有优劣:

  1. CDS Web API(推荐):这是最强大、最自动化的方式。通过Python脚本调用,可以提交任务到后台排队,完成后自动下载。适合批量、定期下载大量数据。你需要注册CDS账号并配置API密钥。
  2. CDS网页界面手动下载:适合一次性、小范围、少量数据的下载。在网站上通过点选方式设置参数,然后提交请求。对于新手理解参数含义很有帮助,但不适合自动化。
  3. 第三方工具或镜像:有些科研机构或数据平台可能会提供ERA5-Land的镜像或简化下载工具,但时效性和完整性可能无法保证,且可能涉及版权和数据政策问题,不推荐作为主要渠道

我们的策略:对于严肃的科研或业务工作,强烈建议掌握CDS API的方式。它虽然前期有一点学习成本,但一旦掌握,后续的数据获取效率是碾压式的。下面我们就重点攻克这种方法。

3. 环境准备与CDS API配置

工欲善其事,必先利其器。在开始写下载脚本前,我们需要把环境搭好。

3.1 注册CDS账号并获取API密钥

  1. 访问 CDS注册页面 并完成注册。
  2. 登录后,进入 您的用户页面 ,找到“API密钥”部分。
  3. 你会看到两行字符串:URLKey。把它们记录下来。

3.2 本地配置API密钥

为了让你的Python脚本能通过CDS认证,需要将密钥保存在本地一个配置文件中。

在Linux/macOS系统上:

# 在终端中执行 echo "url: https://cds.climate.copernicus.eu/api/v2 key: <你的UID>:<你的API密钥>" > ~/.cdsapirc

请将<你的UID><你的API密钥>替换为你网页上看到的实际内容。UID是冒号前的那串数字。

在Windows系统上:

  1. 在文件资源管理器的地址栏输入%USERPROFILE%并回车,进入你的用户目录。
  2. 新建一个名为.cdsapirc的文本文件(注意前面有个点)。
  3. 用记事本打开,写入以下内容:
    url: https://cds.climate.copernicus.eu/api/v2 key: <你的UID>:<你的API密钥>
  4. 保存文件。确保文件名是.cdsapirc,而不是.cdsapirc.txt。你可能需要在“查看”选项中勾选“文件扩展名”来确认。

3.3 安装必要的Python库

打开你的命令行(终端或Anaconda Prompt),创建一个新的虚拟环境(可选但推荐),然后安装核心库:

# 创建并激活虚拟环境(以conda为例) conda create -n era5_download python=3.9 conda activate era5_download # 安装CDS API客户端和数据处理库 pip install cdsapi pip install xarray netCDF4

cdsapi是与CDS服务器通信的核心库。xarraynetCDF4则是后续读取和处理NetCDF数据文件的利器。

4. 核心下载脚本编写与参数详解

配置好环境后,我们就可以动手编写下载脚本了。我将用一个具体的例子,带你一步步走通,并解释每一个参数的含义。

4.1 基础下载脚本框架

假设我们的需求是:下载中国区域2022年全年的逐日2米气温和总降水量数据。

创建一个Python脚本,例如download_era5_land.py,写入以下代码:

import cdsapi import os # 初始化CDS客户端 c = cdsapi.Client() # 定义你的请求参数 request = { 'product_type': 'reanalysis', 'variable': [ '2m_temperature', 'total_precipitation', ], 'year': '2022', 'month': ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12'], 'day': ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31'], 'time': [ '00:00', '01:00', '02:00', '03:00', '04:00', '05:00', '06:00', '07:00', '08:00', '09:00', '10:00', '11:00', '12:00', '13:00', '14:00', '15:00', '16:00', '17:00', '18:00', '19:00', '20:00', '21:00', '22:00', '23:00', ], 'area': [55, 70, 15, 140], # 北,西,南,东 'format': 'netcdf', } # 指定输出文件名 output_file = 'era5_land_china_2022_daily.nc' # 提交下载请求 print(f"正在提交请求,下载数据到: {output_file}") c.retrieve('reanalysis-era5-land', request, output_file) print("下载任务已提交,请等待CDS处理并传输数据。")

参数逐行解析:

  • 'product_type': 'reanalysis':固定为reanalysis,表示再分析产品。
  • 'variable':列表形式,填写你需要的一个或多个变量名。变量名必须与CDS目录中的完全一致。
  • 'year','month','day','time':定义时间维度。注意'time'参数定义了一天中的哪些小时。即使你想要日平均数据,CDS API也不直接提供“日平均”这个选项。你需要下载所有小时数据(00:00到23:00),然后自己用xarray做时间平均。这是新手常踩的坑。上面脚本下载的就是所有小时数据。
  • 'area'[北纬, 西经, 南纬, 东经]。这是定义空间范围最常用的方式。CDS会自动裁剪出这个矩形区域内的数据。
  • 'format': 'netcdf':指定输出格式为NetCDF。

运行这个脚本,它会将任务提交到CDS队列。根据数据量大小(本例中范围大、时间长、变量多、时间分辨率高),任务可能需要排队几分钟到几小时。完成后,数据会自动下载到你脚本所在的目录,名为era5_land_china_2022_daily.nc

4.2 进阶技巧:分块下载与后处理

直接下载全年全球小时数据,文件可能高达数百GB,容易失败且难以处理。更稳健的策略是分而治之

策略一:按时间分块(推荐)一次只下载一个月或一个季度的数据。可以写一个循环:

years = ['2022'] months = ['01', '02', '03'] # 示例:只下前三个月 for year in years: for month in months: request['year'] = year request['month'] = month # 可以只下载特定几天,减少单次请求量 request['day'] = ['01', '02', '03', '04', '05'] request['time'] = ['00:00', '06:00', '12:00', '18:00'] # 甚至可以先下4个时次试试 output_file = f'era5_land_china_{year}_{month}.nc' c.retrieve('reanalysis-era5-land', request, output_file) print(f"{year}-{month} 数据下载完成。")

策略二:按变量分块如果你需要很多变量,但时间范围不长,可以一次只下一个变量,避免单个请求过于复杂。

策略三:下载后合并使用xarray可以轻松合并按时间分块的数据:

import xarray as xr import glob # 找到所有分块文件 file_list = sorted(glob.glob('era5_land_china_2022_*.nc')) # 用xarray打开并沿时间维度合并 ds = xr.open_mfdataset(file_list, combine='by_coords', parallel=True) # 计算日平均(如果需要) ds_daily = ds.resample(time='1D').mean() # 保存为新的文件 ds_daily.to_netcdf('era5_land_china_2022_daily_mean.nc') ds.close()

实操心得:在提交大型请求前,务必先用极小的范围(如一个点、一天、一个变量)测试你的脚本。确保参数无误、网络通畅、API密钥有效。测试成功后再逐步放大请求规模。CDS对单个请求的数据量有限制,分块下载是绕过限制、提高成功率的最佳实践。

5. 数据读取、初步检查与常见单位转换

数据下载到手后,别急着往模型里灌。先做一次“体检”。

5.1 使用Xarray快速查看数据

import xarray as xr ds = xr.open_dataset('era5_land_china_2022_daily_mean.nc') print(ds)

这会打印出数据集的摘要信息,包括维度(经度、纬度、时间)、坐标、数据变量及其属性。重点关注:

  • 变量单位:例如,2m_temperature的单位通常是K(开尔文),total_precipitationm(米)。
  • 时间坐标:检查时间序列是否连续,有没有重复或缺失。
  • 空间范围:检查经纬度边界是否符合你的预期。

5.2 常用单位转换

ERA5-Land数据使用的单位通常是国际单位制(SI),但我们在分析时可能需要转换:

  • 温度:从开尔文(K)转换到摄氏度(°C)。temperature_c = ds['t2m'] - 273.15
  • 降水:从米(m)转换到毫米(mm)。precipitation_mm = ds['tp'] * 1000特别注意:对于小时数据,tp是累积量;对于日数据,如果你是对小时数据做平均,得到的是平均累积率,意义可能不对。通常做法是对小时累积量进行日求和:daily_precip = ds['tp'].resample(time='1D').sum() * 1000
  • 辐射:地表净辐射通常已是W m**-2,可以直接使用。

5.3 可视化快速检查

用几行代码做个简单的空间分布图,直观检查数据是否异常:

import matplotlib.pyplot as plt # 选择某个时间点绘制气温空间图 ds['t2m'].isel(time=0).plot() plt.title('2m Temperature - First Time Step') plt.show() # 绘制某个站点(经纬度点)的时间序列 # 使用最近邻查找,假设站点在(116.4, 39.9) - 北京附近 lon = 116.4 lat = 39.9 # xarray的sel方法支持最近邻查找 ts_temperature = ds['t2m'].sel(longitude=lon, latitude=lat, method='nearest') ts_temperature.plot() plt.title(f'Temperature Time Series at ({lon}, {lat})') plt.show()

6. 常见问题与排查技巧实录

在实际操作中,你几乎一定会遇到下面这些问题。我把我的踩坑记录和解决方案整理如下:

6.1 错误:“Invalid request: Request too large”

问题描述:提交请求后,CDS返回错误,提示请求太大。

原因与解决:这是CDS对单次请求数据量的保护机制。

  1. 最有效的方法:采用前面提到的“分块下载”策略。将长时间序列按年、按月甚至按旬拆分。
  2. 减少空间范围:如果不是必需,尽量不要请求全球数据。
  3. 降低时间分辨率:如果研究允许,先尝试下载逐3小时或逐6小时的数据,而不是逐小时数据。
  4. 减少变量:只选择最核心的变量。

6.2 错误:“Authentication failed”

问题描述:运行脚本时报错,提示认证失败。

原因与解决:API密钥配置有问题。

  1. 检查.cdsapirc文件:确保文件在正确的位置(用户主目录),且内容格式正确,UID和Key没有多余空格或换行。
  2. 验证密钥有效性:可以登录CDS网站,在用户页面查看API密钥状态是否正常。
  3. 环境变量:在某些服务器环境下,也可以通过设置环境变量CDSAPI_URLCDSAPI_KEY来配置,这比文件优先级更高。检查是否有冲突。

6.3 下载任务长时间处于“排队”或“运行”状态

问题描述:任务提交后,在CDS网页的“任务”列表里一直不完成。

原因与解决

  1. 正常排队:CDS是一个全球共享资源,高峰时段排队几小时很正常。耐心等待即可。
  2. 检查任务详情:点击任务ID,查看是否有错误信息。有时是参数设置问题导致任务内部失败。
  3. 任务类型:“再分析”数据(ERA5-Land)是预先计算好的,通常比需要实时计算的“预报”产品快。
  4. 网络问题:偶尔会出现数据传输卡住。可以尝试取消任务,稍后重新提交。

6.4 数据下载中断或文件损坏

问题描述:下载过程中网络中断,导致文件不完整,无法用xarray打开。

原因与解决

  1. 使用CDS API的断点续传cdsapi库本身不支持断点续传。如果中断,通常需要重新提交请求。
  2. 手动处理:对于非常大的文件,可以考虑使用wgetcurl命令来下载CDS提供的临时链接(在任务完成后可见),这些工具支持断点续传。但API方式更规范。
  3. 预防措施:分块下载小文件,是避免因单个大文件下载失败而前功尽弃的最好方法。

6.5 数据时间坐标混乱或存在重复

问题描述:用xarray打开多个文件合并后,发现时间坐标不是单调递增的,或者有重复。

原因与解决

  1. 时区问题:ERA5-Land使用UTC时间。如果你的本地环境或分析脚本没有正确处理时区,可能会导致显示问题。确保所有时间操作都在UTC下进行。
  2. 合并操作不当:使用xr.open_mfdataset时,务必指定combine='by_coords',让xarray根据坐标自动对齐和合并。如果文件间有时间重叠,合并时可能会出错,需要先检查各个文件的时间范围。
  3. 数据本身问题:极少数情况下,CDS的数据文件可能有误。可以对比不同来源或不同下载时间的数据。

6.6 内存不足处理大文件

问题描述:使用xr.open_dataset()直接打开几十GB的NetCDF文件时,内存爆满。

原因与解决:不要一次性将数据读入内存。

  1. 分块读取与延迟计算xarray配合dask可以完美处理这个问题。在打开文件时指定chunks参数:
    ds = xr.open_dataset('large_file.nc', chunks={'time': 100, 'latitude': 100, 'longitude': 100})
    这样数据会以“块”的形式懒加载,只有在实际计算时才会读入相应的块。
  2. 选择性读取:如果只需要特定区域或时间,使用selisel进行索引切片,再加载到内存:
    subset = ds.sel(latitude=slice(20, 50), longitude=slice(100, 130), time=slice('2022-06-01', '2022-08-31')) # 此时subset才是一个实际加载了数据的内存对象
  3. 使用compute():对于基于dask的延迟计算对象,记得在需要结果时调用.compute()

掌握以上这些内容,你基本上就能独立、高效地获取和处理ERA5-Land数据了。整个过程的核心思路就是:明确需求 -> 分块请求 -> 后处理合并 -> 检查验证。这套方法不仅适用于ERA5-Land,对于其他类似的通过API提供的大型气象海洋数据集(如ERA5、CAMS等)也同样有效。数据下载只是第一步,但走稳这一步,后续的分析之路才会更顺畅。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询