我想要生成一个zarr数组,它指向磁盘上的zarr数组的一部分,类似于sliced = np_arr[5]给我一个np_arr视图的方式,这样修改sliced中的数据就可以修改np_arr中的数据。示例代码:
import matplotlib.pyplot as plt
import numpy as np
import zarr
arr = zarr.open(
'temp.zarr',
mode='a',
shape=(4, 32, 32),
chunks=(1, 16, 16),
dtype=np.float32,
)
arr[:] = np.random.random((4, 32, 32))
fig, ax = plt.subplots(1, 2)
arr[2, ...] = 0 # works fine, "wipes" slice 2
ax[0].imshow(arr[2]) # all 0s
arr_slice = arr[1] # returns a NumPy array — loses ties to zarr on disk
arr_slice[:] = 0
ax[1].imshow(arr[1]) # no surprises — shows original random data
plt.show()我有什么可以代替arr_slice = arr[1]写的吗?它能使arr_slice成为磁盘上arr数组的一个(可写的)视图吗?
发布于 2020-11-23 03:36:36
TensorStore库是专门设计来实现的--所有索引操作都会产生延迟视图:
import tensorstore as ts
import numpy as np
arr = ts.open({
'driver': 'zarr',
'kvstore': {
'driver': 'file',
'path': '.',
},
'path': 'temp.zarr',
'metadata': {
'dtype': '<f4',
'shape': [4, 32, 32],
'chunks': [1, 16, 16],
'order': 'C',
'compressor': None,
'filters': None,
'fill_value': None,
},
}, create=True).result()
arr[1] = 42 # Overwrites, just like numpy/zarr library
view = arr[1] # Returns a lazy view, no I/O performed
np.array(view) # Reads from the view
# Returns JSON spec that can be passed to `ts.open` to reopen the view.
view.spec().to_json()您可以在这里更多地了解“索引转换”机制,该机制是这些懒惰视图的基础:space.html#index-transform https://google.github.io/tensorstore/python/indexing.html。
免责声明:我是TensorStore的作者。
发布于 2020-11-23 02:55:31
一种方法是使用自定义存储对象。您可以子类DirectoryStore或任何其他基本存储数据,并覆盖getitem / setitem方法。这可能比你希望的要难。
一个更好的选择是复制Xarray的LazilyIndexedArray类型,这是一个由Stephan:https://github.com/pydata/xarray/blob/master/xarray/core/indexing.py#L516编写的魔术。我想这些能做你想做的事。它们不是Xarray的公共API的一部分,但是它们非常有用,它们实际上应该在一个独立的包中。
在这里也有很好的相关博客文章:https://medium.com/informatics-lab/creating-a-data-format-for-high-momentum-datasets-a394fa48b671
https://stackoverflow.com/questions/64924224
复制相似问题