【问题标题】:xarray.Dataset.to_zarr: overwrite data if exists with append_dimxarray.Dataset.to_zarr:如果存在,则使用 append_dim 覆盖数据
【发布时间】:2020-12-17 11:29:08
【问题描述】:

使用xarray.Dataset.to_zarr,可以将xarray 写入.zarr 文件并使用append_dim 参数沿维度追加新数据。

但是,如果该维度的新数据坐标已经存在,则不会替换现有数据。相反,相同的坐标在结果日期集中出现了两次。

使用来自here的数据的示例:

在这里,我将 2 个数据集写入同一个 .zarr 文件。数据集沿space 维度附加。两个数据集包含相同的空间坐标"IL"

ds_A = xr.DataArray(
    np.random.rand(4, 2),
    [
        ("time", pd.date_range("2000-01-01", periods=4)),
        ("space", ["IA", "IL"]),
    ],
).to_dataset(name="measurements")


ds_B = xr.DataArray(
    np.random.rand(4, 2),
    [
        ("time", pd.date_range("2000-01-01", periods=4)),
        ("space", ["IL", "NY"]),
    ],
).to_dataset(name="measurements")


ds_A.to_zarr("weather.zarr", append_dim="space")
ds_B.to_zarr("weather.zarr", append_dim="space");

读取文件时,第二个数据集并没有覆盖"IL"坐标的数据,而是创建了一个新数据集:

xr.open_zarr("weather.zarr")


<xarray.Dataset>
Dimensions:       (space: 4, time: 4)
Coordinates:
  * space         (space) <U2 'IA' 'IL' 'IL' 'NY'
  * time          (time) datetime64[ns] 2000-01-01 2000-01-02 ... 2000-01-04
Data variables:
    measurements  (time, space) float64 dask.array<chunksize=(4, 2), meta=np.ndarray>

这将是期望的结果:

<xarray.Dataset>
Dimensions:       (space: 3, time: 4)
Coordinates:
  * space         (space) <U2 'IA'  'IL' 'NY'
  * time          (time) datetime64[ns] 2000-01-01 2000-01-02 ... 2000-01-04
Data variables:
    measurements  (time, space) float64 dask.array<chunksize=(3, 2), meta=np.ndarray>

有人知道如果坐标已经存在,是否可以替换数据?

【问题讨论】:

    标签: python dask python-xarray zarr


    【解决方案1】:

    我不认为有一种开箱即用的方法可以做到这一点,附加总是将完整的数据集添加到末尾。

    但是,xarray 的版本 0.16.2 将关键字 region 引入了 to_zarr,它允许您写入 zarr 文件的有限区域。

    您可以使用它来覆盖现有数据:

    # write first dataset
    ds_A.to_zarr("weather.zarr")
    
    # read structure of dataset to see what's on disk
    ds_ondisk = xr.open_zarr('weather.zarr/')
    
    # get index of first new datapoint
    start_ix, = np.nonzero(~np.isin(ds_B.space, ds_ondisk.space))
    
    # region of new data
    region_new = slice(start_ix[0], ds_B.space.size)
    
    # append structure of new data (compute=False means no data is written)
    ds_B.isel(space=region_new).to_zarr("weather.zarr", append_dim='space', compute=False)
    
    # get updated dataset size and create slice
    ds_ondisk = xr.open_zarr('weather.zarr/')
    region_update = slice(start_ix[0], ds_ondisk.space.size)
    
    # write new data to zarr (time needs to be dropped)
    ds_B.drop("time").to_zarr("weather.zarr", region={"space": region_update})
    
    # produces
    xr.open_zarr('weather.zarr/')
    
    <xarray.Dataset>
    Dimensions:       (space: 3, time: 4)
    Coordinates:
      * space         (space) <U2 'IA' 'IL' 'NY'
      * time          (time) datetime64[ns] 2000-01-01 2000-01-02 ... 2000-01-04
    Data variables:
        measurements  (time, space) float64 dask.array<chunksize=(4, 2), meta=np.ndarray>
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-06-06
      • 2022-08-02
      • 1970-01-01
      • 2020-08-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多