美文网首页
[Xarray] 1. 数据结构

[Xarray] 1. 数据结构

作者: Ytlu | 来源:发表于2021-11-13 14:06 被阅读0次

    Xarray的数据结构

    参考Xarray官方文档Python气象数据处理进阶之Xarray(1):Xarray的数据结构

    数据结构

    在Xarray中,数据是由结构和标签的,分为以下几种:

    1.DataArray:

    带有标注或命名维度的多维数组。DataArray将metadata(例如:维名称,坐标和属性)添加到基础的未标记的数据结构,例如numpy和Dask数组。

    2.Datasets:

    具有类似字典结构的尺寸对其的DataArray对象的集合。因此,可以在单个DataArray的维度上执行的大多数操作都可以在Dataset上执行。

    Dataset是多个DataArray的集合

    3.Variable:

    类似于NetCDF的变量。由dimensions,data和attributes组成。variable和numpy数组之间的主要功能区别在于,对variable的数字运算可以通过维名称实现数组广播。

    通俗的讲,variables < DataArray < Dataset (<指包含于)。这种解释不完全正确,但是初学者可以这样理解。

    Xarray中的数据结构如何被识别和标记

    Xarray通过对维命名的操作实现数据筛选和处理,实现数据的标记和命名通过以下几个定义实现:

    *Dimension: 每一轴的维名称(e.g.,('x','y','z'))。

    *Coordinate: 坐标或刻度。类似于字典的序列,将每个点标记。比如说dimension是纬度,那么对应的coordinate就是纬度坐标(90°N,89°N,88°N……89°S,90°S)。

    *Index: 索引号,也可以说是位置标号。a[0]代表a数组的一个数,0就是index。

    
    #CN05.1格点资料
    
    f = xr.open_dataset('CN05.1_Tmax_1961_2017_daily_05x05.nc')
    
    print(f)
    
    #<xarray.Dataset>
    
    #Dimensions: (latitude: 82, longitude: 142, time: 20574)
    
    #Coordinates:
    
    # * longitude (longitude) float64 69.75 70.25 70.75 71.25 ... 139.2 139.8 140.2
    
    # * latitude (latitude) float64 14.75 15.25 15.75 16.25 ... 54.25 54.75 55.25
    
    # * time (time) datetime64[ns] 1961-01-01 1961-01-02 ... 2017-04-30
    
    #Data variables:
    
    # tmax (time, latitude, longitude) float32 ...
    
    #Attributes:
    
    # CDI: Climate Data Interface version 1.6.5rc3 (http://code.zmaw.d...
    
    # Conventions: CF-1.4
    
    # history: Thu Aug 23 09:34:52 2018: cdo -r remapcon,grid05x05 daily/0...
    
    # CDO: Climate Data Operators version 1.6.5rc3 (http://code.zmaw.d...
    
    

    可以看到,该文件是一个Datasets,里面含有变量:Data Variables,数据集的维度有经度纬度和时间,各自有各自的坐标Coordinates,同样数据集还有一些属性来表明数据集信息。

    我们可以通过:

    
    print(f.variables)
    
    print(f.dims)
    
    print(f.coords)
    
    

    来分别查看数据集中包含的变量,维,坐标。

    再比如NCEP的位势高度资料:

    
    f = xr.open_dataset('hgt.1948.nc')
    
    print(f)
    
    #<xarray.Dataset>
    
    #Dimensions: (lat: 73, level: 17, lon: 144, time: 366)
    
    #Coordinates:
    
    # * level (level) float32 1000.0 925.0 850.0 700.0 ... 50.0 30.0 20.0 10.0
    
    # * lat (lat) float32 90.0 87.5 85.0 82.5 80.0 ... -82.5 -85.0 -87.5 -90.0
    
    # * lon (lon) float32 0.0 2.5 5.0 7.5 10.0 ... 350.0 352.5 355.0 357.5
    
    # * time (time) datetime64[ns] 1948-01-01 1948-01-02 ... 1948-12-31
    
    #Data variables:
    
    # hgt (time, level, lat, lon) float32 ...
    
    #Attributes:
    
    # Conventions: COARDS
    
    # title: mean daily NMC Reanalysis (1948)
    
    # description: Data is from NMC initialized reanalysis\n(4x/day). It co...
    
    # platform: Model
    
    # history: created 99/05/11 by Hoop (netCDF2.3)
    
    # References: (http://www.esrl.noaa.gov/psd/data/gridded/data.ncep.reana...
    
    # dataset_title: NCEP-NCAR Reanalysis 1
    
    

    基本同上。

    需要说明的是,ncl数据中存在short格式,在读取时需要使用short2flt()函数,但是在Python中不存在short格式,默认均为float,无需考虑这一点。

    如何创建一个DataArray

    有时我们通过其他手段读取了相关数据,但是数据是np.array格式的,我们需要将其转换为DataArray,亦或我们需要输出一个NC文件,需要将计算后的数组转为DataArray格式,这就用到了创建的方法。

    创建一个DataArray需要什么?

    1.Data: 数据,可以是numpy ndarray,series,DataFrame,pandas.panel等格式

    2.coords: 坐标列表或字典

    如果是列表,则应为元组列表。其中第一个元素为dimension name,第二个元素是对应的坐标array_like对象。

    用字典格式比较好

    3.dims: 维名称列表

    如果省略,并且coords是元组列表,则维度名称取自coords。

    4.attrs: 属性

    5.names: 变量名

    以上,除了data外,都不是必须的。

    创建示例如下:

    
    data = np.array([[1,2,3],[4,5,6]])
    
    level = ['500', '850', '1000']
    
    times = pd.date_range('2000-01-01', periods=2)
    
    foo = xr.DataArray(data, coords=[times, level], dims=['time', 'level'])
    
    print(foo)
    
    #<xarray.DataArray (time: 2, level: 3)>
    
    #array([[1, 2, 3],
    
    # [4, 5, 6]])
    
    #Coordinates:
    
    # * time (time) datetime64[ns] 2000-01-01 2000-01-02
    
    # * level (level) <U4 '500' '850' '1000'
    
    

    上面提到,除了data以外,其他都是不必要的

    
    foo = xr.DataArray(data)
    
    print(foo)
    
    #<xarray.DataArray (dim_0: 2, dim_1: 3)>
    
    #array([[1, 2, 3],
    
    # [4, 5, 6]])
    
    #Dimensions without coordinates: dim_0, dim_1
    
    

    如果是从一个DataFrame数据转化为DataArray的话(这种操作通常是为了将Pandas和Xarray联合使用):

    
    df = pd.DataFrame({'x': [0, 1], 'y': [2, 3]}, index=['a', 'b'])
    
    df.index.name = 'abc'
    
    df.columns.name = 'xyz'
    
    print(df)
    
    #xyz x y
    
    #abc
    
    #a 0 2
    
    #b 1 3
    
    print(xr.DataArray(df))
    
    #<xarray.DataArray (abc: 2, xyz: 2)>
    
    #array([[0, 2],
    
    # [1, 3]])
    
    #Coordinates:
    
    # * abc (abc) object 'a' 'b'
    
    # * xyz (xyz) object 'x' 'y'
    
    

    会自动识别行列的名称和序号。

    官方文档还有更复杂的例子,需要的话再去官网查看。

    在创建了数据之后,我们同样可以使用相关的操作获取DataArray的各种信息:

    
    a = foo.values
    
    a = foo.dims
    
    a = foo.coords
    
    a = foo.attrs
    
    

    如果想对DataArray的值修改可以通过以下两种方法:

    
    foo.values = foo.values+1
    
    foo = foo+1
    
    

    两种结果是等价的,但官方只给出了第一种方法。

    • 通过指令foo.attrs['units'] = 'meters'赋予属性信息,比如给一个单位、备注等等。

    • 通过指令foo.name = 'hgt'赋予名称信息。

    *通过指令foo.rename('temperature')改名,比如通过hgt计算得到了一个新变量,需要改名,就可以用这个指令。

    在得到一个DataArray后,用于画图时,比如我们需要获取它的经度和纬度(在这里,刚刚的例子是时间和高度),那么可以直接通过

    
    foo.coords['time']
    
    foo['time']
    
    

    这两种方式取出坐标信息。

    要修改或者删除某坐标信息的话,原理和修改数据是一样的:

    
    foo['time'] = pd.date_range('1999-01-02',periods = 2)
    
    del foo['time']
    
    

    如何创建一个Dataset

    官网给出一个以气候数据为例的Dataset结构:

    image

    <center>

    display: inline-block;
    
    color: #999;
    
    padding: 2px;">Dataset数据结构
    

    </center>

    一个数据集,包含了数据主体(Temperature,Precipitation),维度坐标(latitude,longitude)。

    根据官网的例子,一个Dataset是这样创建的,实际上与DataArray类似:

    
    temp = 15 + 8 * np.random.randn(2, 2, 3)
    
    precip = 10 * np.random.rand(2, 2, 3)
    
    lon = [[-99.83, -99.32], [-99.79, -99.23]]
    
    lat = [[42.25, 42.21], [42.63, 42.59]]
    
    ds = xr.Dataset({'temperature': (['x', 'y', 'time'], temp),
    
    'precipitation': (['x', 'y', 'time'], precip)},
    
    coords={'lon': (['x', 'y'], lon),
    
    'lat': (['x', 'y'], lat),
    
    'time': pd.date_range('2014-09-06', periods=3),
    
    'reference_time': pd.Timestamp('2014-09-05')})
    
    #<xarray.Dataset>
    
    #Dimensions: (time: 3, x: 2, y: 2)
    
    #Coordinates:
    
    # lon (x, y) float64 -99.83 -99.32 -99.79 -99.23
    
    # lat (x, y) float64 42.25 42.21 42.63 42.59
    
    # * time (time) datetime64[ns] 2014-09-06 2014-09-07 2014-09-08
    
    # reference_time datetime64[ns] 2014-09-05
    
    #Dimensions without coordinates: x, y
    
    #Data variables:
    
    # temperature (x, y, time) float64 15.09 7.656 20.82 ... 2.477 10.53 17.56
    
    # precipitation (x, y, time) float64 3.444 2.694 6.921 ... 7.351 2.099 5.972
    
    

    实际上这个例子与我们通常接触的不太一样,因为大部分数据的lat和lon都是一维的。

    对Dataset的操作和DataArray基本一致,不再重复。

    相关文章

      网友评论

          本文标题:[Xarray] 1. 数据结构

          本文链接:https://www.haomeiwen.com/subject/eywzrktx.html