对多个 xarray DataArrays 取平均值导致没有数据、错误或错误答案

Averaging multiple xarray DataArrays results in no data, errors, or wrong answer

我正在尝试对多个 Xarray DataArray 进行平均,但我得到的结果是错误的。数据没有沿时间维度对齐,但我想对每个数组进行平均,每个数组的每个时间步长都被平均,无论时间坐标是什么。

我的一个 xarrays 如下:

Dimensions:
time: 9125, bnds: 2, lat: 160, lon: 320
Coordinates:
time   (time)    object    1975-01-01 12:00:00 ... 1999-12-...
lat    (lat)     float64   -89.14 -88.03 ... 88.03 89.14
lon    (lon)     float64   0.0 1.125 2.25 ... 357.8 358.9
height ()        float64   ...
Data variables:
time_bnds    (time, bnds)   object    ...
lat_bnds     (lat, bnds)    float64   ...
lon_bnds     (lon, bnds)    float64   ...
tas.      (time, lat, lon). float32.  ...

我的第二个 Xarray 如下:

time.     (time)     object    2065-01-01 12:00:00 ...208912-...
lat       (lat)      float64   -89.14 -88.03 ... 88.03 89.14
lon       (lon)      float64.  0.0 1.125 2.25 ... 357.8 358.9
height.   ()         float64   ...
Data variables:
time_bnds.  (time, bnds).       object   ...
lat_bnds.   (lat, bnds)         float64. ...
lon_bnds.   (lon, bnds).        float64. ...
tas.        (time, lat, lon).   float32. ...

但是,如果数据在时间坐标上对齐,我并不是很感兴趣。我只想找到变量温度的平均值并用平均值创建一个新的 Xarray。我所有的 xarrays 都具有相同的 3 个维度 (time, lat,lon) 和相同的大小 (9125,160,320)

不能 100% 确定您想要实现的目标。因此,您想对所有 3 个 xarray 取时间平均值,从而得到一个只有 'latitude' 和 'longitude'?

维度的 xarray

然后我建议使用 concat 沿维度 'time' 连接 Dataarrays 并简单地应用 mean 函数:

示例:

import xarray as xr

#create some test data
#store 3 dataarrays with random data of shape (time,lat,lon) in a list
data=[]
for i in range(3):
    x=np.random.random((100,10,10))
    data.append(xr.DataArray(x,dims=('time','lat','lon')))

#concatenate along time dimension
data_concat=xr.concat(data,dim='time')
#compute mean
data_concat.mean('time')

xarray 背后的想法是它将 N-dimensional 数组计算模型(例如 numpy 或 dask.array)的特征与 pandas 的 labels-based 索引配对。 Xarray 非常重视维度名称和坐标标签的概念,我强烈建议在深入研究之前先查看 computation using coordinates and also automatic alignment 上的 xarray 文档。

举个具体的例子,就像添加两个索引不匹配的 pandas 系列是行不通的:

In [23]: pd.Series([1, 2], index=[1, 2]) + pd.Series([3, 4], index=[3, 4])
Out[23]:
1   NaN
2   NaN
3   NaN
4   NaN
dtype: float64

如果不以某种方式对齐它们,则不能将两个 xarray DataArray 与 mis-aligned 坐标相加:

In [26]: (
    ...:     xr.DataArray([1, 2], dims=['x'], coords=[[1, 2]])
    ...:     + xr.DataArray([3, 4], dims=['x'], coords=[[3, 4]])
    ...: )
Out[26]:
<xarray.DataArray (x: 0)>
array([], dtype=int64)
Coordinates:
  * x        (x) int64

因此,在您的情况下,尝试对具有相似形状但沿时间维度的标签不匹配的多个数组执行 element-wise 均值,您有几个选择:

  1. 不要使用 xarray

    真的,您要做的是像对待 numpy 数组一样对待 DataArray。你知道表现得像 numpy 的真正好处是什么吗?笨蛋! :) 您可以使用 .data 属性访问任何 DataArray 下的数组:

    mean = (x1['tas'].data + x2['tas'].data + x3['tas'].data) / 3
    
  2. 将您的时间维度更改为位置索引

    另一种选择是用 在数组中对齐的东西替换你的时间暗淡。一种简单的方法是完全删除时间维度,使用 da.reset_index('time'):

    mean = (
        x1['tas'].reset_index('time')
        + x2['tas'].reset_index('time')
        + x3['tas'].reset_index('time')
    ) / 3