[英]Python tile based processing of numpy array
我有一个非常大的 numpy 数组,大小为 [256,256,256,256],占用大约 8GB 内存。
我想使用多处理快速处理数据,类似于基于图块的渲染软件(如搅拌机)使用的方法。
我想将我的数据分成更小的块,为它们创建一个进程列表,当一个完成时,开始处理下一个。 我当前的方法使用 V 拆分,然后循环执行 hsplit 并获取块。 这是一个小得多的数据集的代码示例(9 x 9 分为 3 x 3 块):
import numpy as np
data = np.array(np.arange(0,81)).reshape((9,9))
print(data.shape)
print(data)
print("#"*30)
data = np.array([np.vsplit(set,3) for set in np.hsplit(data,3)])
print(data.shape)
print(data)
print("#"*30)
这并不完全符合我的要求,即创建 9 个 3 x 3 的块,但这是一个小问题。 主要问题是我不认为循环通过这样的数组来应用 vsplit 非常有效,但我不知道内置的 function 会自动执行此操作而无需循环。
我尝试使用 map 来查看它是否以更有效的方式自动应用 vsplit,但时序结果非常相似,所以我认为情况并非如此。 有关如何优化此问题的任何建议?
你想要一些基于as_strided
的东西。 我会在这里推荐我的食谱。 使用它,您可以执行以下操作:
patches = window_nd(data, window = 3, steps = 3)
要传递到多处理,您需要一个生成器。 就像是:
def patch_gen(data, window, **kwargs):
dims = len(data.shape)
patches = window_nd(data, window, **kwargs)
patches = patches.reshape((-1,) + patches.shape[-dims:])
for i in range(patches.shape[0]):
yield patches[i]
您还可以使用来自view_as_blocks
的 view_as_blocks:
def patch_gen(data, window_shape):
dims = len(data.shape)
patches = skimage.util.view_as_blocks(data, window_shape)
patches = patches.reshape((-1,) + patches.shape[-dims:])
for i in range(patches.shape[0]):
yield patches[i]
然后您可以执行以下操作:
with Pool(processors) as p:
out = p.map(func, patch_gen(data, window = 3, steps = 3))
这种方法应该只使用数组的原始 memory 而不是在任何时候复制(我认为)。 这样您就不会浪费时间和 memory 复制原始数据,所有结果都只是指向原始数据的指针。
注意:不要写补丁,至少, 一般来说写as_strided
结果是个坏主意。 如果你没有重叠的 windows 你可能没问题,但是一旦你的 windows 重叠(即steps
< window
)你的手就会一团糟
您可以使用SciKit-Image 的skimage.util.view_as_blocks()
,它可以在不移动或复制任何数据的情况下解决您的阻塞问题。
skimage.util.view_as_blocks(data, (3, 3))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.