3

我想生成一个指向磁盘上 zarr 数组的一部分的zarr数组,类似于如何sliced = np_arr[5]让我查看. 示例代码:np_arrslicednp_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

4

2 回答 2

5

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()

您可以在此处阅读有关这些惰性视图基础的“索引转换”机制的更多信息: https ://google.github.io/tensorstore/index_space.html#index-transform https://google.github.io/tensorstore/python /indexing.html

免责声明:我是 TensorStore 的作者。

于 2020-11-23T03:36:36.407 回答
4

一种方法是使用自定义存储对象。您可以继承DirectoryStore或您的数据所在的任何其他基本存储并覆盖 getitem / setitem 方法。这可能比您希望的要难。

更好的选择是复制 Xarray 的LazilyIndexedArray类型,这是 Stephan Hoyer 所写的魔法:https ://github.com/pydata/xarray/blob/master/xarray/core/indexing.py#L516 。我认为这些正是你想要的。它们不是 Xarray 的公共 API 的一部分,但 IMO 它们非常有用,实际上应该放在一个独立的包中。

这里也有很好的相关博客文章: https ://medium.com/informatics-lab/creating-a-data-format-for-high-momentum-datasets-a394fa48b671

于 2020-11-23T02:55:31.437 回答