Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
基于Python分片的numpy数组处理_Python_Arrays_Numpy_Indexing - Fatal编程技术网

基于Python分片的numpy数组处理

基于Python分片的numpy数组处理,python,arrays,numpy,indexing,Python,Arrays,Numpy,Indexing,我有一个非常大的numpy阵列,大小为[256256],它占用了大约8GB的ram 我希望使用多重处理快速处理数据,类似于基于平铺的渲染软件(如blender)所使用的方法 我想把我的数据分成更小的块,为它们创建一个进程列表,当一个进程完成时,开始下一个进程。我当前的方法使用V分割,然后循环执行hsplit并获取块。下面是一个小得多的数据集9乘9分为3乘3块的代码示例: import numpy as np data = np.array(np.arange(0,81)).reshape((9

我有一个非常大的numpy阵列,大小为[256256],它占用了大约8GB的ram

我希望使用多重处理快速处理数据,类似于基于平铺的渲染软件(如blender)所使用的方法

我想把我的数据分成更小的块,为它们创建一个进程列表,当一个进程完成时,开始下一个进程。我当前的方法使用V分割,然后循环执行hsplit并获取块。下面是一个小得多的数据集9乘9分为3乘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乘3的块,但这是一个小问题。主要的问题是,我不认为通过这样的数组循环来应用vsplit是非常有效的,但我不知道有一个内置函数可以自动执行此操作,而无需循环

我尝试使用map来查看它是否以更有效的方式自动应用vsplit,但计时结果非常相似,因此我认为情况并非如此。关于如何优化这个问题,有什么建议吗?

你想要的是基于大踏步的东西。我推荐。使用此选项,您可以执行以下操作:

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]
with Pool(processors) as p:
    out = p.map(func, patch_gen(data, window = 3, steps = 3))
您还可以使用@NilsWerner中的“视图作为”块:

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]
然后,您可以执行以下操作:

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]
with Pool(processors) as p:
    out = p.map(func, patch_gen(data, window = 3, steps = 3))
这种方法应该只使用数组的原始内存,而不是在我认为的任何时候进行复制。这样,您就不会浪费时间和内存来复制原始数据,所有结果都只是指向原始数据的指针

注意:不要向修补程序写入!至少,如果你没有重叠的窗口,你可能还可以,但一旦你的窗口重叠,即步数你想要的东西是基于步伐的。我推荐。使用此选项,您可以执行以下操作:

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]
with Pool(processors) as p:
    out = p.map(func, patch_gen(data, window = 3, steps = 3))
您还可以使用@NilsWerner中的“视图作为”块:

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]
然后,您可以执行以下操作:

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]
with Pool(processors) as p:
    out = p.map(func, patch_gen(data, window = 3, steps = 3))
这种方法应该只使用数组的原始内存,而不是在我认为的任何时候进行复制。这样,您就不会浪费时间和内存来复制原始数据,所有结果都只是指向原始数据的指针

注意:不要向修补程序写入!至少,如果您没有重叠的窗口,您可能还可以,但一旦窗口重叠,即步骤您可以使用它,它可以在不移动或复制任何数据的情况下解决阻塞问题

skimage.util.view_as_blocks(data, (3, 3))
您可以使用,它解决了阻塞问题,而无需移动或复制任何数据

skimage.util.view_as_blocks(data, (3, 3))

您可能想看看哪个AFAIK实现了与您的策略非常相似的功能。@Paul Panzer我仍然看不出它如何帮助将阵列划分为更小的块。这就是我大部分业绩提升的来源。能够充分利用所有CPU核比处理算法本身的一点小小改进要重要得多。NumExpr将表达式解析为自己的操作码,然后由集成计算虚拟机使用。数组操作数被分割成小块,很容易放入CPU的缓存中并传递给虚拟机。然后,虚拟机对每个块应用这些操作。值得注意的是,表达式中的所有临时变量和常量都是分块的。块分布在CPU的可用内核中,从而实现高度并行的代码执行。这与您正在尝试的不同?您可能想看看哪个AFAIK实现了与您的策略非常相似的东西。@Paul Panzer我仍然看不出它如何帮助将阵列划分为更小的块。这就是我大部分业绩提升的来源。能够充分利用所有CPU核比处理算法本身的一点小小改进要重要得多。NumExpr将表达式解析为自己的操作码,然后由集成计算虚拟机使用。数组操作数被分割成小块,很容易放入CPU的缓存中并传递给虚拟机。然后,虚拟机对每个块应用这些操作。值得注意的是,表达式中的所有临时变量和常量都是分块的。块分布在CPU的可用内核中,从而实现高度并行的代码执行。这与您正在尝试的不同?您也可以使用outlist=True从window\n输出窗口列表,但我正在考虑将其更改为生成器,因为它最终可能会为更大的用例抛出内存错误。谢谢,这正是我想要的。但是,我不知道如何在不复制数据的情况下将数据堆叠回原始形状。最终输出将是所有已处理块的列表。我写了一个例子:@OM22
您是否希望就地更改数据或创建新的输出?如果您绝对确定始终会有不相交的块,您应该能够回写到就地生成的修补程序。如果你的补丁重叠,问题就会发生,你会得到比赛条件和其他一些奇怪的事情,我不是一个足够的CS家伙来解开。小心使用!或者你可以使用下面@NilsWerner的答案,像我一样为你的p.map构建生成器。view_as_blocks比我的配方有更多的内置防护栏,以后也不太可能绊倒你。你也可以使用outlist=True从window_中输出窗口列表,但我正在考虑将其更改为生成器,因为它最终会为更大的用例抛出内存错误。谢谢,这正是我想要的。但是,我不知道如何在不复制数据的情况下将数据堆叠回原始形状。最终输出将是所有已处理块的列表。下面是我写的一个例子:@OM222O您是想就地更改数据还是创建一个新的输出?如果您绝对确定始终会有非相交块,您应该能够将结果回写到相应的补丁中。如果你的补丁重叠,问题就会发生,你会得到比赛条件和其他一些奇怪的事情,我不是一个足够的CS家伙来解开。小心使用!或者你可以使用下面@NilsWerner的答案,像我一样为你的p.map构建生成器。view_,因为_块比我的食谱有更多的内置防护栏,并且不太可能在以后绊倒你。