使用 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()。
我通常编写代码,在其中我必须通过循环不同的选项(稍后将成为坐标)来创建 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()。