关于Xarray在对一个维度求平均或求和后降维的情况,如何把降维的那个坐标系(比如时间)再升回去

存在的问题

不知大家有没有遇到过这样的一个问题:

<xarray.DataArray 'year_data' (time: 61, index: 7)>
array([[20.9,  0.8,  5.3, 19. ,  5.7, 23. , 88. ],
   		……
       [27.9,  1.3,  0. , 26.3,  3.7, 30.9, 80. ]])
Coordinates:
  * time     (time) datetime64[ns] 1992-03-01 1992-03-02 ... 1992-04-30
  * index    (index) <U4 '平均气温' '平均风速' '日降水量' '最低气温' '最大风速' '最高气温' '相对湿度'

这样的一个数据,在求平均后,就只剩下一个坐标系,而时间坐标系就直接不见了。

<xarray.DataArray 'year_data' (index: 7)>
array([20.4,  1.1,  6.7, 18.2 ,  3.4,  23.3, 86.6 ])
Coordinates:
  * index    (index) <U4 '平均气温' '平均风速' '日降水量' '最低气温' '最大风速' '最高气温' '相对湿度'

如果我是想做每个要素的一个年平均,用各年份来进行对比,两个DataArray合并就会出现无法分辨出这个要素的值、出现冲突的情况。
合并错误

解决办法

第一种 重新构造

参考于:https://www.thinbug.com/q/56951314

<xarray.DataArray 'year_data' (time:1, index: 7)>
array([20.4,  1.1,  6.7, 18.2 ,  3.4,  23.3, 86.6 ])
Coordinates:
  * index    (index) <U4 '平均气温' '平均风速' '日降水量' '最低气温' '最大风速' '最高气温' '相对湿度'
  * time     (time) datetime64[ns] 1992-01-01

要把时间维度添加上去的一个办法,就是首先先设置一个二维坐标轴的字典。

然后重新构建一个DataArray,其中的坐标coord选择字典,但是这个时候由于只是一个一维数据,不能添加第二个维度,暂时只有一个"index"。

之后再用concat函数,把时间坐标轴上上去。如下:

coords    = {
    
    'index': slice_data.index, 'time': datetime.datetime(1991, 1, 1)}
slice     = xr.DataArray(slice_data, coords=coords, dims=['index'])
expand_da = xr.concat([slice], 'time')

concat函数具体详看官方目录:https://docs.xarray.dev/en/stable/generated/xarray.concat.html?highlight=concat#xarray.concat

其中要注意的是,concat函数第一个参数必须传入的是一个装 列表list 。不能是一个 DataArray 的数据。

当然这种方法比较的繁琐,我认为最好的办法是第二种。

第二种 assign_coords 与 expand_dims

参考自:https://blog.csdn.net/chengyq116/article/details/95098645

assign_coords 是有添加一个无维坐标轴的一个效果的。(引用自:xarray数据结构之Coordinates)无维坐标是包含坐标数据但不是维坐标的变量,使用assig_coords会达到这种效果:

>>>slice_data.assign_coords(time=datetime.datetime(1991, 1, 1))
<xarray.DataArray 'year_data' (index: 7)>
array([20.4,  1.15,  6.7, 18.2 ,  3.4, 23.3, 86.6])
Coordinates:
  * index    (index) <U4 '平均气温' '平均风速' '日降水量' '最低气温' '最大风速' '最高气温' '相对湿度'
    time     datetime64[ns] 1991-01-01

注意看,无维坐标轴前方没有 * ,同时对于 ‘year_data’ 这个变量而言,影响它的坐标轴只有(index:7)这一个坐标,并没有增加新的维度。

expand_dims 用于给函数增加维度。根据官方文件可以看到。

DataArray.expand_dims(dim=None, axis=None, **dim_kwargs)

传入的只能是一个维度,这个维度不带任何的数值。这就会变成:

>>>slice_data.expand_dims('time')
<xarray.DataArray 'year_data' (time: 1, index: 7)>
array([[20.4,  1.1,  6.7, 18.2 ,  3.4, 23.3, 86.6]])
Coordinates:
  * index    (index) <U4 '平均气温' '平均风速' '日降水量' '最低气温' '最大风速' '最高气温' '相对湿度'
Dimensions without coordinates: time

被认定为无坐标维度。

为了解决这两个函数的问题,我围绕“如何把无维坐标轴变为‘有维’”和“如何给无坐标维度增加坐标”,找了数个小时——

结果当我把这俩函数放一起的时候……

>>>slice_data.assign_coords(time=datetime.datetime(i, 1, 1)).expand_dims('time')
<xarray.DataArray 'year_data' (time: 1, index: 7)>
array([[20.4,  1.1,  6.7, 18.2 ,  3.4, 23.3, 86.6]])
Coordinates:
  * index    (index) <U4 '平均气温' '平均风速' '日降水量' '最低气温' '最大风速' '最高气温' '相对湿度'
  * time     (time) datetime64[ns] 1992-01-01

emmm……答案竟然离我这么近!

另外需要注意的是

对于 DataArray 这种格式的数据,调用 .assign_coords 和 .expand_dims 并不会对原本的多维数组作出改变,需要进行赋值操作。

而相对的,对于 list 列表这种格式而言,使用 .remove 方法时候,会直接影响到 list 本身里的内容,而可以不进行赋值操作。

猜你喜欢

转载自blog.csdn.net/weixin_48458238/article/details/126485233
今日推荐