使用 Xarray 迭代创建 DataArray 的大多数 straightforward/compact 方法

Most straightforward/compact way to iteratively create a DataArray with Xarray

我通常编写代码,在其中我必须通过循环不同的选项(稍后将成为坐标)来创建 DataArray。自从我开始使用 Xarray 以来,我一直通过创建较小的 DataArray 列表然后将它们连接起来来做到这一点:

import numpy as np
import xarray as xr

extradims = range(3)
size = 5

da_total = []
for cj, extradim in enumerate(extradims):
    data = np.random.normal(scale=cj, size=size)
    da = xr.DataArray(data, dims=['sample'], coords=dict(sample=range(size)))
    da_total.append(da)
dafinal = xr.concat(da_total, dim='extradim').assign_coords(extradim=extradims)

然而,与 Xarray 所做的其他事情相比,这似乎非常麻烦。所以我想知道我是否缺少更简单的方法。特别是,我想避免使用“外部”工具(如列表和 numpy),而只使用 Xarray 来完成所有事情。我得到的最接近的是这样做:

samples = range(5)
nans = np.full([len(extradims), len(samples)], np.nan)
dafinal2 = xr.DataArray(nans, dims=['extradim', 'sample'],
                        coords=dict(extradim=extradims, sample=samples))
for cj, extradim in enumerate(extradims):
    data = np.random.normal(scale=cj, size=len(samples))
    da = xr.DataArray(data, dims=['sample'], coords=dict(sample=samples))
    dafinal2.loc[dict(extradim=extradim)] = da

这在循环中更紧凑一些,但我想避免必须事先创建 NaNs 数组。有时我在开始循环之前不知道某些坐标的大小,所以最好避免这种情况。

理想情况下我可以这样做:

dafinal3 = xr.DataArray(dims=['extradim', 'sample'])
for cj, extradim in enumerate(extradims):
    data = np.random.normal(scale=cj, size=len(samples))
    da = xr.DataArray(data, dims=['sample'], coords=dict(sample=samples))
    dafinal2.loc[dict(extradim=extradim)] = da

但这当然行不通。

有没有办法实现我想要的?

编辑: 请参阅 xarray 主要贡献者在类似问题上的 。它确认您使用的模式同样有效。


coordinates 是必需的参数。 DataArray 不会神奇地扩展其网格。如果你真的事先不知道坐标,那么 xr.concat 就是要使用的函数。

如果你事先知道坐标,那么你可以初始化一个空的 DataArray,这几乎是你的最后一个例子。

>>> da = xr.DataArray(coords=(range(3), range(4)))                                               
>>> da
<xarray.DataArray (dim_0: 3, dim_1: 4)>
array([[nan, nan, nan, nan],
       [nan, nan, nan, nan],
       [nan, nan, nan, nan]])
Coordinates:
  * dim_0    (dim_0) int64 0 1 2
  * dim_1    (dim_1) int64 0 1 2 3

您可能想要选择默认值和维度名称:

>>> da = xr.DataArray(None, coords=dict(x=range(3), y=range(4)), dims=("x", "y"))              
>>> da                  
<xarray.DataArray (x: 3, y: 4)>
array([[None, None, None, None],
       [None, None, None, None],
       [None, None, None, None]])
Coordinates:
  * x        (x) int64 0 1 2
  * y        (y) int64 0 1 2 3

在某些情况下,更好的替代方法可能是填充数据集,然后对其调用 .to_array()