xarray.Dataset.to_zarr:如果存在 append_dim,则覆盖数据
xarray.Dataset.to_zarr: overwrite data if exists with append_dim
使用 xarray.Dataset.to_zarr 可以将 xarray 写入 .zarr
文件并使用 append_dim
参数沿维度附加新数据。
但是,如果该维度的新数据的坐标已经存在,则不会替换现有数据。相反,相同的坐标在生成的数据集中出现了两次。
使用来自 here 的数据的示例:
在这里,我将 2 个数据集写入同一个 .zarr 文件。数据集沿 space
维度附加。两个数据集包含相同的 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>
有谁知道如果坐标已经存在,是否可以替换数据?
我认为没有现成的方法可以做到这一点,附加总是将完整的数据集添加到末尾。
但是,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>
使用 xarray.Dataset.to_zarr 可以将 xarray 写入 .zarr
文件并使用 append_dim
参数沿维度附加新数据。
但是,如果该维度的新数据的坐标已经存在,则不会替换现有数据。相反,相同的坐标在生成的数据集中出现了两次。
使用来自 here 的数据的示例:
在这里,我将 2 个数据集写入同一个 .zarr 文件。数据集沿 space
维度附加。两个数据集包含相同的 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>
有谁知道如果坐标已经存在,是否可以替换数据?
我认为没有现成的方法可以做到这一点,附加总是将完整的数据集添加到末尾。
但是,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>