ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

ERA5数据下载指南:从账号注册到Python批量获取

ERA5数据下载指南:从账号注册到Python批量获取 1. 最先卡住你的不是Python代码而是账号注册和API Key获取说实话下载ECMWF的ERA5数据大部分人以为难点在用Python写请求代码上结果真正动手才发现最先卡住你的是账号注册和API Key获取这一环。我见过太多人在这一步折腾了半小时甚至跑去问客服为什么登录不上。ERA5数据不是直接挂在一个公开网址上让你点击下载的而是通过CDSClimate Data Store平台分发。你要使用Python脚本批量下载就必须先做两件事注册账号、拿到属于你自己的API Key。这就像你去银行办事得先开户拿卡ATM才让你存取款。1.1 注册流程里容易踩的坑ECMWF的注册页面上有几个细节特别容易让人困惑。首先网站会区分个人用户和机构用户如果你是学生或者独立研究者选择Individual个人类别就行。填单位名称时学校名称要写官方全称不要随手写个缩写否则审核可能会打回来。更关键的是邮箱验证。ECMWF系统发出的验证邮件有时候会被QQ邮箱、163邮箱扔进垃圾箱我在实验室带新人的时候几乎每隔一段时间就会遇到这种情况。建议优先用机构邮箱或者Gmail注册验证邮件点击后需要在24小时内完成激活过期了就得重新发。还有一个很多人不知道的点注册后系统会给你分配一个UIDUser ID这串数字在后续配置里必须用到。当初我找这个UID找了好几分钟因为它没有摆在个人主页的显眼位置而是藏在Personal details页面里。1.2 获取API Key的正确路径登录之后进入个人主页找到API request或者Install CDS API key相关的入口点击进去就能看到你的API Key。这个Key是一长串字母数字组合对应的是你个人的访问凭据。这里要特别提醒API Key等同于你的账号密码千万不要把它写进公开的代码仓库里尤其是推送到GitHub上。我见过不止一个学生把key直接写在Jupyter Notebook里然后传到GitHub结果被爬虫扫到账号直接被滥用。正确做法是把它存到本地配置文件中用的时候由程序自动读取代码里只保留读取命令不接触具体key值。后文会详细说。注意API Key的获取页面实际上有两种界面版本旧版界面在User profile里新版界面在API Key独立菜单下。如果你找不到就在页面右上角搜索框里直接输入API key。2. 环境准备cdsapi安装与配置文件里的那些坑拿到API Key之后下一步就是在本地Python环境里安装CDS官方提供的下载库——cdsapi。这一步本身不难但我在实际帮助别人排查的过程中发现配置环节的报错率反而比写代码阶段还要高。2.1 安装cdsapi时的版本选择安装命令很简单常规做法是pip install cdsapi如果你的机器上同时存在Python 2和Python 3记得用pip3而不是pip否则库可能会装到旧版本环境里。另外我强烈建议你在虚拟环境里操作而不是直接装在系统Python里。比如用conda创建独立环境conda create -n era5 python3.9 conda activate era5 pip install cdsapi xarray netcdf4xarray和netcdf4虽然不是下载必需的但下载完总要看看数据内容吧提前装上后面就省事了。如果你在国内直接pip install可能速度慢甚至超时可以临时用清华源pip install cdsapi -i https://pypi.tuna.tsinghua.edu.cn/simple2.2 配置文件~/.cdsapirc的精确写法cdsapi库在工作时会自动读取一个名为.cdsapirc的配置文件路径在用户主目录下。Linux和macOS是~/.cdsapircWindows则是C:\Users\你的用户名\.cdsapirc。文件内容格式如下url: https://cds.climate.copernicus.eu/api key: 你的UID:你的APIKey注意key那一行是UID加冒号加API Key冒号必须是英文冒号不要用中文冒号。UID和API Key之间没有空格。很多人的报错就出在这里比如整串key被系统识别为无效或者连不上CDS服务器第一反应通常会怀疑网络问题但实质上就是这里的格式不对。我建议配置完成后先运行下面这段代码验证连通性import cdsapi c cdsapi.Client()如果配置有问题它会直接报Invalid API Key或者Missing credentials之类的错误这样就能第一时间发现问题而不是等下载请求真正发出后才被拒。2.3 Windows用户尤其要注意文件命名Windows系统默认会隐藏文件扩展名你创建.cdsapirc的时候很容易弄成.cdsapirc.txt。这个文件后缀名不会阻止系统读取但一旦你在命令行里输入cd ~后再用cat .cdsapirc检查看到的内容是空的就会怀疑人生。稳妥做法是在文件管理器里打开查看-文件扩展名选项手动确认文件名称里没有.txt结尾或者更简单直接在命令行中用记事本打开创建notepad C:\Users\你的用户名\.cdsapirc在记事本里粘贴内容然后直接点保存让它按原文件名落盘。3. 理解ERA5的数据组织方式才能写对请求参数很多教程一上来就甩给你一段完整代码看起来好像很简单但你一旦想改点东西就抓瞎了。原因是你没有理解ERA5数据本身的组织逻辑。这一步跳过了后面连为什么报错都看不懂。ERA5数据集在CDS上主要分成两大类这两类对应的Python请求地址是完全不同的数据集名称覆盖内容典型用途reanalysis-era5-single-levels地表或单层变量如2米气温、海平面气压、降水气候统计、地表过程研究reanalysis-era5-pressure-levels多个气压层上的变量如位势高度、温度、风速天气学分析、高空环流研究你在写请求前必须先想清楚我要的数据是单层的还是分层的。3.1 变量名称不是靠猜的要去官方列表查这是新手最容易翻车的地方。你想下载2米温度以为参数写成temperature_2m结果在ERA5数据集里它的正式名称是2m_temperature你想下载降水以为写成precipitation但实际名称是total_precipitation。变量名称必须严格匹配CDS系统里注册的条目名一个字母都不能差。好在ECMWF提供了完整的变量列表页面在数据集详情页里直接搜关键字就行。比如你想找风速按CtrlF搜wind_speed能看到完整的变量标识符。3.2 坐标参数area的边界效应下载区域数据时area参数用于指定西北和东南角的经纬度顺序是[N, W, S, E]。例如area [55, 70, 15, 140]这表示北纬55度、东经70度为西北角北纬15度、东经140度为东南角。这个顺序很多人会写成反的或者分不清W和E导致下载完才发现区域错位。另外ERA5的经度范围是0到360。如果你想下载西经区域的数据比如东经105度到西经75度也就是105E到285E你不能填负数而应该直接写105/285或者拆成两个请求分别下。这一点在使用标准地理坐标系习惯的人身上特别容易出错。3.3 时间变量里的月平均与逐小时差异ERA5的数据时间粒度有三种可选逐小时、逐日、逐月。同一个变量不同时间粒度的数据请求语法一致但是下载体积差很多。举个例子下载全球范围1980年到2020年逐小时2米气温数据单文件能到几十GB同样范围换成年平均数据可能只有几百MB。新手如果真需要逐月数据却在请求里不小心选了逐小时磁盘瞬间就能被塞满。所以动手写代码前先确认这几件事我要研究的问题需要什么时间分辨率需要哪些变量需要什么空间范围全球还是区域需要哪些年份和月份建议把答案写在注释里然后再转化成代码参数这样能大幅减少误操作。4. 从单文件下载到批量任务实操代码的三层递进理解了数据结构后代码本身其实没什么高深的。我按单次下载-批量下载-进阶处理三层来演示我日常实际在用的代码每一层都配了详细的注释你可以直接复制去改。4.1 最简下单下载某一天的单层变量import cdsapi dataset reanalysis-era5-single-levels request { product_type: [reanalysis], variable: [2m_temperature], year: [2020], month: [01], day: [15], time: [00:00, 06:00, 12:00, 18:00], data_format: netcdf, download_format: unarchived } client cdsapi.Client() client.retrieve(dataset, request).download(era5_2m_t_20200115.nc)这段代码的执行逻辑是向CDS提交一个请求系统把你的需求加入任务队列完成后返回一个可下载的NetCDF文件。几个参数需要重点说明product_type对ERA5来说固定填reanalysis。timeUTC时刻按需填你填了哪些时刻输出文件里就会有对应时刻的变量。data_format推荐netcdf方便后续用xarray处理如果只想快速看数据也可以选grib。第一次运行这个脚本你可能会在终端看到Request accepted之类的提示然后进入等待状态。下载完成后同目录下就会生成一个.nc文件。4.2 批量下载多年数据并自动跳过已存在文件实际研究中单天数据远远不够用。比如你想做近20年的夏季平均气温分析就需要2000年6-8月每天的数据。这时候可以循环提交请求但要注意两点不要一次性把几百个月的数据塞进一个请求里任务队列会过长容易超时或被服务器拒绝。循环过程中要加一个文件已存在就跳过的判断避免中途中断后重新下载浪费流量。import cdsapi import os dataset reanalysis-era5-single-levels variables [2m_temperature] years [2000, 2001, 2002] months [06, 07, 08] client cdsapi.Client() for year in years: for month in months: filename fera5_2m_t_{year}{month}.nc if os.path.exists(filename): print(f{filename} 已存在跳过) continue request { product_type: [reanalysis], variable: variables, year: [year], month: [month], day: [f{d:02d} for d in range(1, 32)], time: [f{h:02d}:00 for h in range(0, 24, 6)], data_format: netcdf, download_format: unarchived } client.retrieve(dataset, request).download(filename)这里有几个细节值得说day参数用列表表达式生成了1到31日Careful2月没有31日CDS会自动忽略不存在的日期不会报错可以放心用。文件命名用年月做区分后续处理时方便按文件名批量读取。每次请求只有一个月的数据单文件大小通常可控不至于因为网络闪断而功亏一篑。4.3 下载气压层数据并固定区域如果你需要的是高空位势高度比如研究副热带高压的位置变化那就要用reanalysis-era5-pressure-levels数据集同时加上pressure_level和area参数import cdsapi dataset reanalysis-era5-pressure-levels request { product_type: [reanalysis], variable: [geopotential], pressure_level: [500], year: [2020], month: [06], day: [01], time: [12:00], area: [55, 70, 15, 140], data_format: netcdf } client cdsapi.Client() client.retrieve(dataset, request).download(era5_z500_20200601.nc)位势高度在ERA5变量里叫geopotential单位是m²/s²不是位势米。你要转成常用的gpm位势米需要除以重力加速度9.80665。这是很多人拿到数据后才发现的问题。加了area参数后下载量大幅缩减。全球数据一个时次的500hPa位势高度文件大约几十MB但限制到中国区域后只有几MB速度差别非常明显。5. 下载超时、队列排队、磁盘爆满实测中的典型问题代码能跑通只是第一步实际下载过程中出现的幺蛾子多到让人头大。我把这几年自己碰到的问题集中列一下都是原汁原味的实战经验。5.1 CDS任务队列早上提交晚上才轮到的心理准备ERA5数据下载机制是异步的。你提交请求后任务进入CDS服务器队列后台按顺序处理。如果你提交的数据量大或者恰好赶上高峰期比如全球很多高校都在做夏季研究等上几个小时甚至一天都是正常的。不要因为终端里长时间没动静就去强制中断进程那样只会浪费之前的排队。我的习惯是提交任务后开启日志记录让脚本定时检查状态如果任务还在队列里就去干别的事过一阵子再回来看。5.2 超时中断与断点续传cdsapi库本身没有内置断点续传功能网络一断已经下载到一半的文件就废了。这个问题在下载大文件时尤其致命。我的应对策略很简单修改请求参数把大任务拆成小任务每个任务的文件控制在几百MB以内同时配合os.path.exists判断中断后重新运行脚本就能跳过已完成的部分。另一种思路是用系统级工具辅助让Python脚本先生成所有下载链接然后交给curl或wget下载并配合-c参数实现断点续传。但这需要进入CDS后台获取带token的链接操作相对复杂一般批量任务才值得这么折腾。5.3 磁盘空间估算与实际占用ERA5 NetCDF文件的大小大致可以根据变量数量、时间层数、空间范围估算。以单层变量为例全球范围一个时次约0.25度分辨率单个变量文件大约是几十MB。逐小时数据乘以24一个月就是天文数字。所以我在跑批量下载前会先估算总量# 估算一个月的文件大小 estimate_mb 30 * 4 * 60 # 30天*4时次*约60MB print(f预计单个文件大小: {estimate_mb} MB)实测下来全球范围、0.25度、单变量、4时次/天、30天的NetCDF文件大约在7到10GB之间。搞清楚量级后再对照磁盘剩余空间该加硬盘就加硬盘别等下载一半才发现存不下。5.4 常见报错及排查路径我把这几年遇到频率最高的几类错误整理成了表格方便你直接对照排查报错信息本质原因解决思路Invalid API Key配置文件的key格式错误或key失效检查.cdsapirc里UID正确、英文冒号分隔、无多余空格400 Bad Request请求参数不合法比如变量名拼写错误去数据集详情页核对变量名和参数类型Request queue too long你的账号同时提交了过多任务适当合并请求减少任务数量HTTP Error 403网关拦截常见于频繁请求放慢请求频率增加sleep间隔No data available时间范围超出数据覆盖期确认ERA5数据起止年份早期年份只有部分变量我自己的排查习惯是先把request参数打印出来逐项对照官方文档然后检查配置文件最后才怀疑网络问题。大部分时候问题都出在参数拼写和配置文件上别急着怪网络。6. 处理速度慢用区域裁剪和变量精简给请求瘦身下载速度和数据量直接相关很多人嫌下载慢但其实现行方案还能再优化。这里分享几个我实测有效的提速思路。6.1 在请求端做区域裁剪而不是下载后再裁剪不少人的习惯是先下载全球数据再用xarray裁出目标区域。但全球数据的下载时间和磁盘占用是区域数据的几十倍聪明做法是在request里直接写入area参数让服务器返回裁剪后的结果。比如研究青藏高原区域可以设为area: [40, 70, 25, 105]这样服务器端就只返回北纬25到40度、东经70到105度的数据下载量从几十GB变成几百MB速度提升立竿见影。6.2 按需精简变量而不是一次下一堆同一个数据集下变量越多文件越大。你如果只是做水汽通量分析就别把温度、风速、位势高度全下载下来。只保留specific_humidity和wind_speed两个变量请求处理时间会明显缩短。另外data_format和download_format也有讲究。默认的grib格式比netcdf体积更小但后续处理需要用cfgrib库netcdf通用性好适合绝大多数Python处理流程。我一般选netcdf兼容性优先。6.3 多任务并行下载的可行性与风险CDS允许同一账号同时提交多个任务但服务器资源的公平使用原则是不要滥用。如果你确实有多个独立请求要下可以在脚本里用多进程方式同时提交任务让它们在队列里并列处理from concurrent.futures import ThreadPoolExecutor def download_one(spec): client cdsapi.Client() client.retrieve(spec[dataset], spec[request]).download(spec[filename]) tasks [spec1, spec2, spec3] with ThreadPoolExecutor(max_workers3) as executor: executor.map(download_one, tasks)不过我很少把并发数开到超过5。网络带宽、CDS限流都是现实约束盲目开几十个线程最后往往是被服务器暂时限制访问反而得不偿失。稳妥的做法是并发2到3个任务配合每个任务尽量精简参数。6.4 下载完成后的数据校验文件下载完不代表万事大吉我遇到过几次文件看起来正常、但用xarray打开就报错的情况原因是下载过程中网络抖动导致文件不完整。一个简单的校验方法是检查文件大小是否在合理范围内或者直接用xarray尝试打开import xarray as xr ds xr.open_dataset(era5_2m_t_20200115.nc) print(ds)如果这一步能正常打印出维度信息和变量说明文件基本完整。如果报Unexpected EOF之类的错就删掉重新下载这个文件。打开之后还能顺手确认一下坐标范围和缺失值情况。这个习惯能帮你省下后面数据分析阶段大量的排错时间。我在实际使用中发现ERA5下载这件事真正让人崩溃的往往不是数据获取本身而是各种藏在配置、参数和网络细节里的小坑。把这些坑提前避开整条流程就能顺畅很多。
返回列表