import xarray as xr
import numpy as np
import pandas as pd
data = np.random.randn(4,3,2) #随机生成三维数组
xr.DataArray(data) #简单的dataarray
times = pd.date_range('2000-01-01',periods=4)
lat = [0,1,2]
lon = [10,20]
da = xr.DataArray(
data,
coords={
'time'=times,
'lat'=lat,
'lon'=lon
},
dims=['time','lat','lon']
)
da.dims #获取维度
da.coords #获取坐标
da.values #获取数值
type(da.values)
da.attrs #获取属性
da.attrs['name']='precitation' #设置属性
da.attrs['units']='mm'
da.rename('rain')
可以理解为多个DataArray的集合
#1.直接创建
temp = 15+8*np.random.randn(4,3,2)
precip = 10*np.random.randn(4,3,2)
xr.Dataset(
{
'temperature'=(['time','lat','lon'],temp)
'precipitation'=(['time','lat','lon'],precip)
},
coords={
'lon'=lon
'lat'=lat
'time'=times
}
)
#2.使用DataArray创建
xr.Dataset({'precip':da})
xr.Dataset({
'precip':da,
'temp':da+10
})
ds.data_vars #显示有哪些变量
'temp' in ds #判断变量是否在Dataset中
ds.coords
ds._coord_names #获取坐标名
ds._dims #获取维度
ds.drop_vars('temp') #剔除变量
ds.drop_dims('time') #剔除维度
#xarray.open_dataset() engine=netcdf4/cfgrib
import xarray as xr
ds = xr.open_dataset('filename') #engine默认netcdf4
ds.longitude
ds.longitude.values
ds.time
type(ds.time.values)
ds['latitude']
ds['t2m']
ds['t2m'].values
#xarray.open_dataarray #只能打开含有一个变量
da = xr.open_dataset('filename',drop_variables=['u10','v10','swh'])
da = xr.open_dataarray('filename',drop_variables=['u10','v10','swh'])
da = xr.open_dataarray('filename')
xr.open_dataset('fd.grib2',engine='cfgrib') #打开后发现缺少t2m类似其他坐标系统里的变量1
xr.open_dataset('fd.grib2',engine='cfgrib',
backend_kwargs={
'filter_by_keys':{
'typeOfLevel':'heightAboveGround',
'level':2
}})
xr.open_dataset('fd.grib2',engine='cfgrib',
backend_kwargs={
'filter_by_keys':{
'typeOfLevel':'surface',
'level':0
}})
# xarray.open_mfdataset(paths,engine=' ')
xr.open_dataset('filename')
xr.open_mfdataset('../*.nc') #mfdataset也可以读取一个文件
:在指定维度位置上输入相应的数值来索引,只能在dataArray中使用
#1.通过数字查找
import xarray as xr
xr.open_dataset('filename')
t = ds['t2m']
t.values
t.values.shape
t[0,0,0] #得到的是dataArray
t[:,1,1]
#2.标签查找
t.loc[:,89.75,70.25]
t.loc[:,89.75:80,70.25:71] #维度从大到小排列,经度从小到大排列
:索引时输入相关的维度名称和相应的数值
#1.数字查找
ds.isel(longitude=1,time=0) #1是位置,没有查找的坐标全部都取
#2.标签查找
ds.sel(longitude=70.25,latitude=50,time='2020-01-01') #70.25是值
#3.时空的切片索引
#空间索引
ds.sel(latitude=slice(80,50),longitude=slice(80,155))
ds.sortby('latitude') #按照latitude排序
ds.sel(latitude=slice(50,80),longitude=slice(80,155))
#时间索引
ds.sel(time=slice('2020-02-03','2020-05')
ds.sel(time='2020-01-01 06')
ds.sel(time=(ds.time.dt.day==15)) #指定15号
ds.sel(time=(ds.time.dt.month.isin([1,3,5]))) #提取1,3,5月的数据
import xarray as xr
ds = xr.open_dataset('filename')
#1.修改坐标名字
ds.rename({
'longitude':'x',
'latitude':'y'})
#2.修改坐标数值
ds.assign_coords(longitude=ds['longitude']+180)
#3.时间坐标拆分
yearv= = ds.time.dt.year
monthv = ds.time.dt.month
dayv = ds.time.dt.day
hourv = ds.time.dt.hour
ds_time = ds.assign_coords(year=yearv,month=monthv,day=dayv,hour=hourv) #只定义进去了但没有和变量关联起来
ds1 = ds_time.set_index(time_new=('year','month','day','hour')) #增加坐标到dimension里
ds1.sel(time_new=(2020,1,15,[0,12]))
ds1.drop_dims('time').unstack('time_new') #但time是和变量关联的,删除之后变量也没了,所以要修改
#修改上面三步
ds1 = ds_time.set_index(time=('year','month','day','hour'))
ds1.sel(time=(2020,1,15,[0,12]))
time = ds1.unstack('time_new')
time.sel(day=15,hour=18)
#1.增加坐标
t = ds['t2m'].expand_dims(height=1) #但还没有关联到变量里,还没有赋值
t.assign_coords(height=[2])
#2.删除坐标
t.squeeze('height') #只能把维度是1的坐标压缩(应该意思是只有一个值的维度吧)
import xarray as xr
#1.四则运算
ds = xr.open_dataset('....nc')
t = ds['t2m']
t.values
t-273.15
u = ds['u10']
v = ds['v10']
u ** 2 + v ** 2 #风速的平方
#2.常用函数
t.max()
t.min()
t.mean()
t.std()
import numpy as np
np.max(t) #和上面结果一样
np.sqrt(u**2 +v**2)
abs(u)
遇到缺测值可以自动忽略
#1.时间降维
t.mean()
t.mean(dim='time') #年平均气温
t-t.mean(dim='time') #距平气温
#2.空间降维
t.mean(dim=['latitude','longitude'])
时间分辨率有:year、month、day、hour、minute、second、microsecond、season、dayofyear、dayofweek、days_in_month
#xarray.DataArray.groupby(group,squeeze= ,restore_coord_dims= )
t.groupby('time.month')
t.groupby('time.season')
tmonth = t.groupby('time.month')
tmonth.groups
for i,data in t_month:
print(i,data['time'])
tmonth.mean() #时间维度变成month
:是在简单平均数基础上,通过顺序逐期增减新旧数据求算滑动平均,借以消除偶然变动因素,找出事物发展趋势,并进行预测的方法。
#xarray.DataArray.rolling(dim=None,center=False,min_periods=None)
t_time = t.mean(['longitude','latitude'])
r = t_time.rolling({'time':5})
r.mean() #前五个是nan
r = t_time.rolling(time=5,center=True)
r.mean() #前2个和最后2个是nan
r.max() #其他函数也可以用
#空间平滑
t_region = t.mean('time')
r = t_region.rolling(longitude=5,latitude=5,center=True)
r.mean()
#Xarray.DataArray.interp(coords= ,method= ,...)
#算法有:多维:linear、nearest;一维:linear、nearest、zero、slinear、qadratic、cubic
#1.一维插值
t_oneday = t.sel(time='2020-01-01') #有四个时间 0,6,12,18
t_oneday.time
import pandas as pd
new_time = pd.data_range(t_oneday.time.values[0],t_oneday.time.values[-1],freq='3H')
t_oneday.interp(time=new_time) #插值成功
#2.多维插值
t_region = t_t.sel(longitude=slice(100,101),latitude=slice(41,40)) #slice左右都是闭的
import numpy as np
nlat = np.linspace(41,40,11)
nlon = np.linspace(100,101,11)
t_region.interp(longitude=nlon,latitude=nlat)
画图对象:dataarray,使用matplotlib库
一维数据:line();二维数据:pcolormesh();其他:hist()
import xarray as xr
da = xr.open_dataset('....nc')
t = da['t2m']-273.15
t_point = t.isel(latitude=10,longitude=10) #10是位置
t_point.plot()
t_month = t_point.groupby('time.month').mean()
t_month.plot()
#多个点的时间序列
tp = t.isel(latitude=[10,100,200],longitude=10)
tp.plot() #结果是堆叠的hist
tp.plot(hue='latitude') #得到不同latitude的折线图
t_season = t.sel(longtitude=slice(90,120),latitude=slice(50,20)).groupby('time.season').mean()
t_season.iseal(season = 0).plot()
t_season = t.sel(longtitude=slice(90,120),latitude=slice(50,20)).groupby('time.season').mean()
g = t_season.plot(col='season',col_wrap=2) #col_wrap是两行的意思
g.axes
tp = t.isel(latitude=[10,100,200],longitude=[10,100,200])
tp.plot(row='latitude',col='longtitude')
把不要的数据隐藏起来的最简便的方法就是设为nan,计算和可视化过程都不参与
#xarray.where(cond,x,y,keep_attrs=None)
import xarray as xr
import numpy as np
ds = xr.open_dataset('...nc')
u = ds['u10']
v = ds['v10']
ws = np.sqrt(u**2+v**2)
ws_region = ws.mean('time')
ws_region.plot()
xr.where(ws_region >5,ws_region,np.nan).plot()
1.shp文件 ;2.salem掩膜工具
#1.陆地掩膜
import geopandas as gpd
import salem
land_shp = gpd.read_file('filename')
land = ws_region.salem.roi(shape = land_shp) #region of interest
land.plot()
#2.海洋掩膜
ocean_shp = gpd.read_file('filename')
ocean = ws_region.salem.roi(shape = ocean_shp)
ocean.plot()
#3.行政区划掩膜
china_shp = gpd.read_file('filename')
china = ws_region.salem.roi(shape = china_shp)
select = china_shp[china_shp['省'].isin(['广东省','河南省'])]