繁体   English   中英

Python 基于瓦片的 numpy 数组处理

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM