对多个 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 均值,您有几个选择:
不要使用 xarray
真的,您要做的是像对待 numpy 数组一样对待 DataArray。你知道表现得像 numpy 的真正好处是什么吗?笨蛋! :) 您可以使用 .data
属性访问任何 DataArray 下的数组:
mean = (x1['tas'].data + x2['tas'].data + x3['tas'].data) / 3
将您的时间维度更改为位置索引
另一种选择是用 在数组中对齐的东西替换你的时间暗淡。一种简单的方法是完全删除时间维度,使用 da.reset_index('time')
:
mean = (
x1['tas'].reset_index('time')
+ x2['tas'].reset_index('time')
+ x3['tas'].reset_index('time')
) / 3
我正在尝试对多个 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 均值,您有几个选择:
不要使用 xarray
真的,您要做的是像对待 numpy 数组一样对待 DataArray。你知道表现得像 numpy 的真正好处是什么吗?笨蛋! :) 您可以使用
.data
属性访问任何 DataArray 下的数组:mean = (x1['tas'].data + x2['tas'].data + x3['tas'].data) / 3
将您的时间维度更改为位置索引
另一种选择是用 在数组中对齐的东西替换你的时间暗淡。一种简单的方法是完全删除时间维度,使用
da.reset_index('time')
:mean = ( x1['tas'].reset_index('time') + x2['tas'].reset_index('time') + x3['tas'].reset_index('time') ) / 3