xr.Dataset:
装入多个变量的信息,可以对每个变量进行定义不同的维度信息。主要包含以下三部分:
- data_vars
- coords
- attrs
xarray.Dataset(*data_vars=None*, *coords=None*, *attrs=None*)
1、官方例子:
#创建数据 np.random.seed(0) temperature =np.random.randn(2, 2, 3) precipitation =np.random.rand(2, 2, 3) lon = [[-99.83, -99.32], [-99.79, -99.23]] lat = [[42.25, 42.21], [42.63, 42.59]] time = pd.date_range("2014-09-06", periods=3) reference_time = pd.Timestamp("2014-09-05") #将创建的数据填入dataset ds = xr.Dataset( data_vars=dict( temperature=(["x", "y", "time"], temperature), precipitation=(["x", "y", "time"], precipitation), ), coords=dict( lon=(["x", "y"], lon), lat=(["x", "y"], lat), time=time, reference_time=reference_time, ), attrs=dict(description="Weather related data."), ) ds #显示创建的dataset
其实,有点复杂,下面我举一个简单一点的例子:
ds = xr.Dataset( data_vars={ "a": (("x", "y"), np.ones((3, 3))),#生成 3*3的都是1的数组,('x','y')表示维度信息 "b": ("t", np.full(4, 1), {"b atrri": "b value"}), #填充都是1的一维数组 }, # 创建坐标 coords={ "longtitude":("x",[-1, 0, 1]), #[]里的就是对应的数值 "latitude":("y",[-1, 0, 1]), "time":("t",["2021-09-01", "2021-09-02", "2021-09-03", "2021-09-04"]) }, #创建 属性信息 attrs={"attr": "example"} ) ds
创建dataset时需要注意的一点是:data_vars中的维度个数应该与坐标中的数据个数对应上,比如下面数据中,创建一个3*3的数组,那么坐标中的len(经、纬度)也应该是 3
ds = xr.Dataset( data_vars={ "a": (("x", "y"), np.ones((3, 3))) }, # 创建坐标 coords={ "longtitude":("x",[-1, 0, 1]), #[]里的就是对应的数值 "latitude":("y",[-1, 0, 1]) }, #创建 属性信息 attrs={"attr": "example"} ) ds
2、同一维度上多个变量的坐标参数:
xa = np.arange(1, 4) xb = np.arange(1, 5) a = xr.DataArray(np.linspace(0, 1, 3), dims="x", coords={"x": xa}) b = xr.DataArray(np.zeros(4), dims="x", coords={"x": xb}) xr.Dataset(data_vars={"a": a, "b": b})
xr.DataArray:
装入一个变量的信息
import numpy as np import xarray as xr import pandas as pd
1、有多个维度时(以3维为例)
da = xr.DataArray( # 温度数据 建立一个3*4*2的全是1的numpy,几*几取决于数据量 np.ones((3, 4, 2)), # 维度名称 dims=("x", "y", "t"), # 数组名称 name="Temperature Data", # 坐标数据 字典形式 x方向有三个数据 coords={"longtitude":("x",[0,90,180]), "latitude":("y",[-90,-45,45,90]), "time":("t",['2021-09-01','2021-09-02']) }, #加入 数据属性说明 attrs={'autor':'jianpu'} )
2、只有一个维度时
# 一个维度的情形 x=xr.DataArray([1, 2], dims=("x") )
以上都可以通过:
da.dims da.name da.coords da.attrs
查看相关的维度、名称、坐标、属性等参数
直接在运行命令中输入:
da
可以显示xarray.DataArray相关设置
输入:
da.data
可以直接提取da的数据
同时,在coords中,可以通过
{"key":value}#注意,以上都是英文拼写
为经纬度等数据添加更多的属性
1.http://xarray.pydata.org/en/stable/generated/xarray.Dataset.html
2.http://xarray.pydata.org/en/stable/generated/xarray.DataArray.html(dataarray)
xarray–数据的读写
利用xarray读取NetCDF数据:
其中,对于xarray读取的nc文件生成的数据对象,可以通过一些函数转为pandas
对象。对pandas
对象使用to_xarray
方法或者对 xarray
对象使用to_pandas
方法进行转换。
但是,不能直接对于dataset
进行转换,需要先处理为dataArray
才能进行转换,也就是指定需要转换的变量。
还是举一个之前的例子,先创建一个dataset
:
import numpy as np import xarray as xr import pandas as pd da = xr.DataArray( np.ones((3, 4, 2)), dims=("x", "y", "t"), name="Temperature Data", coords={"longtitude":("x",[0,90,180]), "latitude":("y",[-90,-45,45,90]), "time":("t",['2021-09-01','2021-09-02']) })
比如,我要对于时间数据进行转换,只需要输入:
da.time.to_series()
或者
da.time.to_pandas()
以上两种方法都可以实现,对于其他的数据,操作方法类似,取决于你确定的或者读取的数据坐标名称。
同样的,反过来也是如此,只是换个函数:
to_dataframe
:将DataArray
或Dataset
对象转换为pandas.dataframe
。
基于此,我们下面介绍对于nc文件的读取:
NetCDF
:通过函数open_dataset
`、open_dataarray
将nc数据进行读、to_netcdf
写
下面举一个例子:
读取nc文件:
#导入库 import xarray as xr #nc文件所在的绝对路径 path='D:\\data\\sst.nc' #在python中需要使用双斜杠 # 读入文件 data=xr.open_dataset(path)
读取nc文件后,可以在终端输入data,查看文件的相关信息,进行下一步的数据处理
写入nc文件:
ds = xr.Dataset( data_vars={ "a": (("x", "y"), np.random.randn(4, 2)), "b": (("z", "x"), np.random.randn(6, 4)), }, coords={ "x": np.arange(4), "y": np.arange(-2, 0), "z": np.arange(-3, 3), },)
将 DataSets
和 DataArray
写入 nc 文件中
# DataSets写入文件ds.to_netcdf("data.nc")# DataArray写入文件ds.a.to_netcdf("dataArray.nc")
xarray–数据索引和切片
为了更好的处理数据,可以通过xarray对数据进行索引和切片,实现更好、更快的处理。
import numpy as np import xarray as xr import pandas as pd array = np.random.randn(3,4) #生成一个3行4列(3×4)的随机数组arraydata= xr.DataArray(array, dims=("x","y")) data
方法1:.isel
(integer selection)是一个基于维度名称数字索引的筛选的方法。通过.isel
这个方法筛选了arr第一维度x索引值为1和第二维度y索引值为2的值。
data.isel(x=1, y=2)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dGhyEga8-1630891998095)(E:\myblog\blogname\source_posts\paper2\image-20210903231658248.png)]
方法2:使用坐标名称筛选数据,使用的是.sel方法而非.isel方法。
data = xr.DataArray( np.random.randn(6,6), dims=("x","y"), coords={ "x":[1,2,3,4,5,6], "y":pd.date_range("2021-09-05", periods=6, freq="M") }) data.sel(x=5)
或者也可以这样写
data.loc[{"x":5}]
当然,我们读取的nc文件处理的肯定都是经纬度以及时间等数据,下面给出几个筛选数据的例子:
1、筛选前20个纬度坐标且第20至40个经度坐标的数据:
data.isel(lat=slice(None,20), lon=slice(20, 40))
2、筛选南北纬30度且时间在2019年1月1日至2019年10月1日的数据
lat_range=lat[(lat>=-30) & (lat<=30)] data.sel(lat=lat_range, time=slice("2019-01-01", "2019-10-1"))
3、去除经度250280的数据,经度排列为0360
data.drop_sel(lon=[250.0, 280.0])
xarray–nc文件规则网格插值
创建一个数组例子:
import numpy as np import xarray as xr import pandas as pd data = xr.DataArray( np.random.randn(6,6), dims=("x","y"), coords={ "x":[1,2,3,4,5,6], "y":pd.date_range("2021-09-05", periods=6,freq="M") }) data
有时候想要知道格点框中更加高分辨率的值,这时候可以使用interp函数进行数据插值。
data.interp( x=np.linspace(2, 6, 10), y=pd.date_range("2021-04-01", "2021-04-30",freq="D"))
假如我现在需要将一个原始为1* 1 °分辨率的nc文件,插值为目标为0.25*0.25°分辨率的数据,可以这样操作:
import xarray as xr import netCDF4 as nc path1='D:\\ss\\data.nc' da=xr.open_dataset(path1) path2='D:\\ss\\目标data.nc' ds=xr.open_dataset(path2) ss= ds.interp(lat=da.lat.values, lon=da.lon.values)