gpt4 book ai didi

python - 基于numpy中的内核提取子数组

转载 作者:太空宇宙 更新时间:2023-11-04 04:04:58 25 4
gpt4 key购买 nike

我想知道是否有一种有效的方法可以从更大的 numpy 数组中获取子数组。

我拥有的是 np.where 的应用程序。我“手动”迭代 xy 作为偏移量,并将带有内核的 where 应用于从具有适当尺寸的较大数组中提取的每个矩形。

但是在numpy的方法集合中有更直接的方法吗?

import numpy as np

example = np.arange(20).reshape((5, 4))

# e.g. a cross kernel
a_kernel = np.asarray([[0, 1, 0], [1, 1, 1], [0, 1, 0]])

np.where(a_kernel, example[1:4, 1:4], 0)
# returns
# array([[ 0, 6, 0],
# [ 9, 10, 11],
# [ 0, 14, 0]])


def arrays_from_kernel(a, a_kernel):
width, height = a_kernel.shape
y_max, x_max = a.shape
return [np.where(a_kernel, a[y:(y + height), x:(x + width)], 0)
for y in range(y_max - height + 1)
for x in range(x_max - width + 1)]


sub_arrays = arrays_from_kernel(example, a_kernel)

这将返回我需要进一步处理的数组。

# [array([[0, 1, 0],
# [4, 5, 6],
# [0, 9, 0]]),
# array([[ 0, 2, 0],
# [ 5, 6, 7],
# [ 0, 10, 0]]),
# ...
# array([[ 0, 9, 0],
# [12, 13, 14],
# [ 0, 17, 0]]),
# array([[ 0, 10, 0],
# [13, 14, 15],
# [ 0, 18, 0]])]

上下文:类似于 2D 卷积,我想在每个子数组上应用自定义函数(例如平方数的乘积)。

最佳答案

目前,您正在数据上手动推进一个滑动窗口 - 步幅技巧来拯救! (不,这不是我编造的——实际上在 numpy 中有一个名为 stride_tricks 的子模块!)而不是手动将窗口构建到数据中,然后调用 np.where() 在它们上面,如果你有一个数组中的窗口,你可以只调用一次 np.where()。 Stride 技巧允许您创建这样的数组,而无需复制数据。

让我解释一下。 numpy 中的普通切片创建原始数据的 View 而不是副本。这是通过引用原始数据,但更改用于访问数据的步幅(即在两个元素或两行之间跳转多少,等等)来完成的。步幅技巧允许您比切片和 reshape 更自由地修改这些步幅,因此您可以例如。多次迭代相同的数据,这在这里很有用。

让我演示一下:

import numpy as np

example = np.arange(20).reshape((5, 4))
a_kernel = np.array([[0, 1, 0], [1, 1, 1], [0, 1, 0]])

def sliding_window(data, win_shape, **kwargs):
assert data.ndim == len(win_shape)
shape = tuple(dn - wn + 1 for dn, wn in zip(data.shape, win_shape)) + win_shape
strides = data.strides * 2
return np.lib.stride_tricks.as_strided(data, shape=shape, strides=strides, **kwargs)

def arrays_from_kernel(a, a_kernel):
windows = sliding_window(a, a_kernel.shape)
return np.where(a_kernel, windows, 0)

sub_arrays = arrays_from_kernel(example, a_kernel)

关于python - 基于numpy中的内核提取子数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57538406/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com