替换 DataArray 中的所有数据

Replace all data in DataArray

仅更改 DataArray 中的数据的最佳做法是什么?

是不是给data属性赋值那么简单?我在文档中没有看到执行此操作的正确方法。

import xarray as xr
import numpy as np
import pandas as pd

# Example in DataArray
rng = np.random.default_rng(123)
temperature = 15 + 8 * rng.standard_normal((2, 2, 3))
lon = [[-99.83, -99.32], [-99.79, -99.23]]
lat = [[42.25, 42.21], [42.63, 42.59]]
time = pd.date_range("2014-09-06", periods=3)
reference_time = pd.Timestamp("2014-09-05")
da = xr.DataArray(data=temperature,
                  dims=["x", "y", "time"],
                  coords=dict(lon=(["x", "y"], lon),
                              lat=(["x", "y"], lat),
                              time=time,
                              reference_time=reference_time),
                  attrs=dict(description="Ambient temperature.",
                             units="degC"))
# Some new data
temperature_new = 20 + rng.standard_normal((2, 2, 3))
# Below seems like a very fragile mechanism
da.data = temperature_new

是的,你可以!

当您将新数组分配给 da.data 时会发生什么情况,即 xarray 将 dataarray 指向的对象替换为您的新数组:

In [2]: a = np.arange(5)
   ...: b = np.ones(shape=5)

In [3]: hex(id(a)) # get the address of a
Out[3]: '0x119a0b1b0'

In [4]: hex(id(b)) # get the address of b
Out[4]: '0x119a0b150'

In [5]: da = xr.DataArray(a, dims=('x', ), attrs={'myattr': 1})

In [6]: da
Out[6]:
<xarray.DataArray (x: 5)>
array([0, 1, 2, 3, 4])
Dimensions without coordinates: x
Attributes:
    myattr:   1

In [7]: hex(id(da))  # get the address of the DataArray
Out[7]: '0x119a2ddc0'

In [8]: hex(id(da.data))  # note the address of da.data matches a
Out[8]: '0x119a0b1b0'

In [9]: da.data = b  # assign the data to b

In [10]: da  # we have the same data array, but with new values
Out[10]:
<xarray.DataArray (x: 5)>
array([1., 1., 1., 1., 1.])
Dimensions without coordinates: x
Attributes:
    myattr:   1

In [11]: hex(id(da))  # same data array address
Out[11]: '0x119a2ddc0'

In [12]: hex(id(da.data))  # but now our data matches b
Out[12]: '0x119a0b150'

xarray 检查以确保替换数据具有正确的形状:

In [12]: da.data = np.ones(shape=(3, 4))
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-12-cbd0cc0cc7f2> in <module>
----> 1 da.data = np.ones(shape=(3, 4))

~/miniconda3/envs/rhodium-env/lib/python3.9/site-packages/xarray/core/common.py in __setattr__(self, name, value)
    265         """
    266         try:
--> 267             object.__setattr__(self, name, value)
    268         except AttributeError as e:
    269             # Don't accidentally shadow custom AttributeErrors, e.g.

~/miniconda3/envs/rhodium-env/lib/python3.9/site-packages/xarray/core/dataarray.py in data(self, value)
    638     @data.setter
    639     def data(self, value: Any) -> None:
--> 640         self.variable.data = value
    641
    642     @property

~/miniconda3/envs/rhodium-env/lib/python3.9/site-packages/xarray/core/variable.py in data(self, data)
    348         data = as_compatible_data(data)
    349         if data.shape != self.shape:
--> 350             raise ValueError(
    351                 f"replacement data must match the Variable's shape. "
    352                 f"replacement data has shape {data.shape}; Variable has shape {self.shape}"

ValueError: replacement data must match the Variable's shape. replacement data has shape (3, 4); Variable has shape (5,)

但是,如果您要用分布式 dask 数组替换 numpy 空数组,xarray 将无缝地开始使用新数据。这是一个功能!