Dask 在不重新写入整个数据集的情况下,将新的Xarray DataArray添加到现有的Zarr存储中?
如何将新的Dask 在不重新写入整个数据集的情况下,将新的Xarray DataArray添加到现有的Zarr存储中?,dask,python-xarray,zarr,Dask,Python Xarray,Zarr,如何将新的DataArray添加到现有的数据集,而不覆盖整个内容?新的DataArray与现有阵列共享一些坐标,但也有新的坐标。在我当前的实现中,数据集被完全覆盖,而不仅仅是添加新内容 现有的DataArray是一个块化的zarr-backedDirectoryStore(尽管我对S3存储也有同样的问题) 将numpy导入为np 将xarray作为xr导入 进口南非兰特 arr1=xr.DataArray(np.random.randn(2,3), [('x',['a','b']),('y',[
DataArray
添加到现有的数据集
,而不覆盖整个内容?新的DataArray
与现有阵列共享一些坐标,但也有新的坐标。在我当前的实现中,数据集
被完全覆盖,而不仅仅是添加新内容
现有的DataArray
是一个块化的zarr-backedDirectoryStore
(尽管我对S3存储也有同样的问题)
将numpy导入为np
将xarray作为xr导入
进口南非兰特
arr1=xr.DataArray(np.random.randn(2,3),
[('x',['a','b']),('y',[10,20,30]),
name='arr1')
ds=arr1.chunk({'x':1,'y':3})
ds
如下所示:
尺寸:(x:2,y:3)
协调:
*不幸的是,(据我所知)目前这是不可能的。追加模式中的to_zarr
用于向维度添加新条目,而不是向已写入的条目添加变量
@davidbrochart在最初的MR中为用例写了一篇好文章:
将xarray作为xr导入
作为pd进口熊猫
ds0=xr.Dataset({'temperature':(['time'],[50,51,52]),coords={'time':pd.date_range('2000-01-01',periods=3)})
ds1=xr.Dataset({'temperature':(['time'],[53,54,55]),coords={'time':pd.date_范围('2000-01-04',periods=3)})
ds0.to_zarr('temp')
ds1.to_zarr('temp',mode='a',append_dim='time'))
ds2=xr.open\u zarr('temp')
您将看到ds2
是时间维度上ds0
和ds1
的串联版本
好消息是,可以选择直接与zarr商店交互。如果您查看xarray的实现,您会发现在底层库中添加新变量实际上是一种可能性。然而,这并没有在xarray API中实现。这个问题发布已经有一段时间了——但也许它仍然对某些人有用(对我来说是!)
xarray
的0.16.2版
将关键字region引入了to_zarr
,允许您写入zarr文件的有限区域。这似乎使您能够将新变量添加到现有数据集中,而无需完全覆盖它
在您将ds
写入zarr并在内存中创建新的ds2
之后,我的解决方案就会启动,然后再将其写回
首先,我将每个zarr内容的修改时间保存在字典中,以便在第二次写入后检查是否确实没有任何变化:
导入操作系统
导入glob
mtimes={}
内容=列表(glob.glob(“test.zarr/arr/*”)
对于目录中的c:
更新({c:os.path.getmtime(c)})
现在我可以写回新变量了。要使用region
关键字,我需要删除任何已经存在且两个变量相同的变量:
ds2_drop=ds2.drop([“x”、“y”、“z”、“arr1”])
现在,我可以编写新变量并检查修改时间(如果确实没有任何更改):
ds2_.to_zarr(“test.zarr/”,mode=“a”,group='arr',region={“x”:切片(0,ds2.x.size),“z”:切片(0,ds2.z.size)})
对于目录中的c:
断言os.path.getmtime(c)=mtimes[c]
#一切都好!
如果我们再次从zarr加载数据集,我们可以看到新变量已成功添加:
打印(xr.open\u zarr(“test.zarr/”,group=“arr”))
尺寸:(x:2,y:3,z:3)
协调:
*x(x)