获取 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 的作者。
我想生成一个指向磁盘上 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 的作者。