如何使用python处理nc数据制作Mike风场文件--以ERA5数据为例

时间:2024-11-21 08:05:20

@如何使用python处理nc数据制作Mike风场文件
NetCDF(network Common Data Form)网络通用数据格式是一种面向数组型并适于网络共享的数据的描述和编码标准。nc格式文件被广泛应用于气象、海洋、环境、地质等专业。目前可下载的大气再分析风场数据,如CCMP、ERA5、NCEP等均提供此格式的数据。本次我们以ERA5再分析数据为例演示如何通过python制作mike的dfs2风场文件。

1. ERA5风场数据得下载

ERA5数据下载的网站为/cdsapp#!/dataset/reanalysis-era5-single-levels?tab=form,变量我们选择其中的10m u-component of wind10m v-component of windSurface pressure下载,下载时间、空间范围根据实际需求自定义。
ERA5下载变量选择界面

2. python读取nc数据

首先导入需要用到的模块,其中前面3个为制作Mike文件相关的模块,Dataset为读取nc文件的模块,datetime为时间处理模块。

from mikeio import Dfs2
from mikeio.eum import ItemInfo, EUMUnit
from mikeio.eum import EUMType
import numpy as np
from netCDF4 import Dataset
import datetime as dt
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

读取文件代码如下:

file = Dataset('.\\')  #文件路径及名称
time =file['time'][:]   #读取时间信息
lon = file['longitude'][:]   #读取经度信息
lat = file['latitude'][:]   #读取纬度信息
u = file['u10'][:]   #读取东西风速u
v = file['v10'][:]   #读取南北风速v
p = file['sp'][:]   #读取表面压强
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

值得注意的是,根据现有文献,在海陆交界处的ERA5风速偏小,因此研究近海的朋友们可对风场数据适当方法,例如:

u=u*1.1   #将风速放大1.1倍
v=v*1.1
  • 1
  • 2

3. 处理时间信息

nc文件中的时间信息往往是自某一时刻以来的多少小时(或者天、月)的形式来表达,如下图所示,此时很难直观地感受具体时间。
nc文件中对于时间的描述
nc文件中时间的数据
因此使用daatetime模块的timedelta函数对时间进行处理:

time_dt=[]   #指定一个新的列表
tstart = dt.datetime(1900,1,1,0)   #nc文件的起始时刻
for i in time:
        time_dt.append(tstart+dt.timedelta(hours=int(i)))  #将nc文件中的时刻转换为正常的时间格式

  • 1
  • 2
  • 3
  • 4
  • 5

处理后的时间time_dt如下图所示:
处理后的时间数据

4. 制作dfs2文件

接下来就是最后的dfs2的制作过程,首先做一些准备工作:

dfsfilename = '2015uvp_for_fm.dfs2'   #给定文件名
 #设置dfs2文件左下角的坐标原点,在ERA5文件中,经度排列方式为从东向西,纬度排列方式为从北向南,
 #因此原点的经度为lon的第1个点,原点的纬度为lat的最后一个点
x0=lon[0]      
y0=lat[-1]
coordinate = ['LONG/LAT',x0,y0,0]   #设置原点
dx=0.25 #设置网格间距,ERA5默认网格间距均为0.25度
dy=0.25
time0 = time_dt[0]   #设置其实时间,用到了上一步的时间处理
delta_t = 3600   #设置时间间隔,ERA5数据时间间隔为1h,3600s
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

制作dfs2:

#创建变量, EUMType.Wind_Velocity说明变量类型为风速, EUMUnit.meter_per_sec说明变量单位为m/s
items = [ItemInfo("u", EUMType.Wind_Velocity, EUMUnit.meter_per_sec),
        ItemInfo("v", EUMType.Wind_Velocity, EUMUnit.meter_per_sec),
         ItemInfo("p", EUMType.Pressure, EUMUnit.pascal)]
d = [u,v,p]   #将要输出至dfs2的数组打包
dfs = Dfs2()   #实例化一个dfs变量
dfs.write(filename=dfsfilename,data=d,start_time=time0,dt=delta_t,
			items=items,coordinate=coordinate,dx=dx,dy=dy) #输出变量
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

最后让我们来看一下制作好的dfs2文件:
在这里插入图片描述
并与nc文件的数据进行一下比较:
在这里插入图片描述
显然,dfs2文件的数据是合理的,可以应用于Mike21、Mike3的水动力模块、谱波模块,其中,水动力模块需要u、v、p三个变量,谱波模块只需要u、v两个变量。