获取 zarr 数组切片的视图

Getting a view of a zarr array slice

我想生成一个指向磁盘上 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 数组的(可写)视图吗?

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

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

相关博客 post 也很不错: https://medium.com/informatics-lab/creating-a-data-format-for-high-momentum-datasets-a394fa48b671

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 的作者。