使用Python脚本从 Copernicus Climate Data Store (CDS) 检索气象数据
具体地,需要检索变量(geopotential、relative_humidity、temperature、u_component_of_wind、v_component_of_wind、vertical_velocity)在各种不同的压力水平、不同的日期和时间、以及在特定地理区域内的值。
使用了 CDS API 客户端来执行检索,保存结果到 NetCDF 格式的文件中,文件名是由年、月、日和时间组成的。
首先进入该网站
ERA5 hourly data on pressure levels from 1959 to present (copernicus.eu)
勾选想要下载的数据范围和变量
生成api
但是不能直接复制,右键网页的任意位置,点击 “检查”
点击红色框圈选的按钮,之后将鼠标移动到代码部分,单击左键
右侧界面就会自动跳转到这段代码对应的网页脚本,点击<pre前面的箭头,将这段脚本展开
右键后,选择编辑文本 或 编辑为HTML,就可以复制代码了
代码如下,最后所有数据都会下载到一个名为download.nc的文件中
import cdsapi
c = cdsapi.Client()
c.retrieve(
'reanalysis-era5-pressure-levels',
{
'product_type': 'reanalysis',
'format': 'netcdf',
'variable': [
'geopotential', 'relative_humidity', 'temperature',
'u_component_of_wind', 'v_component_of_wind', 'vertical_velocity',
],
'pressure_level': [
'450', '500', '550',
'600', '650', '700',
'750', '775', '800',
'825', '850', '875',
'900', '925', '950',
'975', '1000',
],
'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': [
35.5, 116, 30,
122,
],
'year': [
'2017', '2018', '2019',
'2020', '2021', '2022',
],
},
'download.nc')
当数据量较大的时候,该文件难以读取,导致无法进一步对数据进行分析。这个时候就需要将大数据进行细分处理,我采取的办法是通过循环的方法按小时读取数据。
一年有365天,一天有24小时,一共5年的数据,也就是说有5*365*24=43800个文件,我通过年月时日的格式对这些文件命名,如2017010421.nc文件表示的是2017年1月4日21时的数据。
同时,因为下载的时候容易受网络影响中断下载,万一下载了20000个文件的时候中途断开了,重新运行代码又要重复下载,因此我引入os库判断目标文件是否已经存在,存在则跳过。
最后,2月没有30天,每个月的天数不完全相同,默认31天会导致CDS服务器报错。引入calendar库,判断当前年,当前月份有几天。最后生成字符串列表,不足两位的需要在前面补零。
import cdsapi
import os
import calendar
variables = [
'geopotential', 'relative_humidity', 'temperature',
'u_component_of_wind', 'v_component_of_wind', 'vertical_velocity'
]
pressure_levels = [
'400', '450', '500',
'550', '600', '650',
'700', '750', '775',
'800', '825', '850',
'875', '900', '925',
'950', '975', '1000'
]
years = [
'2017', '2018', '2019',
'2020', '2021', '2022'
]
months = [
'01', '02', '03',
'04', '05', '06',
'07', '08', '09',
'10', '11', '12'
]
days = [
'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'
]
times = [
'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 = [35.5, 116, 30, 122]
c = cdsapi.Client()
for year in years:
for month in months:
num_days = calendar.monthrange(int(year), int(month))[1]
days = [str(i).zfill(2) for i in range(1, num_days+1)]
for day in days:
for time in times:
saveas = year + month + day + time[:2] + '.nc'
if os.path.isfile(saveas):
# print(f"{saveas} 已存在,跳过下载")
continue
request = {
'product_type': 'reanalysis',
'format': 'netcdf',
'variable': variables,
'pressure_level': pressure_levels,
'year': year,
'month': month,
'day': day,
'time': time,
'area': area,
}
c.retrieve('reanalysis-era5-pressure-levels', request, saveas)
os库和calendar库都是python自带的,而cdsapi库需要自行安装,进入命令行,输入
pip install cdsapi -i https://pypi.tuna.tsinghua.edu.cn/simple/
写在最后,如果运行代码出现如下报错信息,是因为没有在用户目录下配置cds的api调用许可文件,具体解决办法参考下面这篇博客即可。
Exception: Missing/incomplete configuration file: C:\Users\Administrator/.cdsapirc
Python使用CDS API时,报Exception: Missing/incomplete configuration错误_没有文件叫cdsapi_bug嘛我经常写的博客-CSDN博客