Python 用numpy将M*N矩阵的每个3x3窗口求和为M/3*N/3矩阵
我试图实现一个求和(或最终求平均值)的函数 给定矩阵的每个3x3窗口,并使用每个窗口的结果创建一个小9倍的矩阵 我想不出一个高效简洁的方法来使用numpy实现这一点 有什么想法吗Python 用numpy将M*N矩阵的每个3x3窗口求和为M/3*N/3矩阵,python,image-processing,numpy,scipy,Python,Image Processing,Numpy,Scipy,我试图实现一个求和(或最终求平均值)的函数 给定矩阵的每个3x3窗口,并使用每个窗口的结果创建一个小9倍的矩阵 我想不出一个高效简洁的方法来使用numpy实现这一点 有什么想法吗 谢谢大家! 为了准确实现您的要求,我将在图像上应用[3x3]框过滤器,然后使用最近邻插值调整矩阵大小 # Pseudo code kernel = np.array([[1/9, 1/9, 1/9], [1/9, 1/9, 1/9], [1/9
谢谢大家! 为了准确实现您的要求,我将在图像上应用
[3x3]
框过滤器,然后使用最近邻插值调整矩阵大小
# Pseudo code
kernel = np.array([[1/9, 1/9, 1/9],
[1/9, 1/9, 1/9],
[1/9, 1/9, 1/9]])
avg_data= ndimage.convolve(data, kernel)
smaller_data = scipy.misc.imresize(avg_data, org_size/3, interp='nearest', mode=None)
如果您想要更高效的服务,正如@Jaime所指出的,您可以这样做:
当您试图理解发生了什么时,请记住,跨步表示我们需要在内存中偏移多少字节才能遍历到每个维度中的下一个单元格。因此,如果您处理的是
int32
数据类型,它将是4
的倍数。最简单的仅使用numpy的方法,它所做的卷积工作要少得多,因此可能比基于文件管理器的方法更快,就是将原始数组调整为具有额外维度的数组,然后将新尺寸相加,将其还原为正常值:
>>> arr = np.arange(108).reshape(9, 12)
>>> rows, cols = arr.shape
>>> arr.reshape(rows//3, 3, cols//3, 3).sum(axis=(1, 3))
array([[117, 144, 171, 198],
[441, 468, 495, 522],
[765, 792, 819, 846]])
如果需要平均值,只需将结果数组除以元素数:
>>> arr.reshape(rows//3, 3, cols//3, 3).sum(axis=(1, 3)) / 9
array([[ 13., 16., 19., 22.],
[ 49., 52., 55., 58.],
[ 85., 88., 91., 94.]])
此方法仅在阵列的形状本身是3的倍数时才有效。scipy.misc.imresize(arr,size,interp='bilinear',mode=None)您可以通过切片来完成最后一步,即
avg_data[1::3,1::3]
提供正确的结果,几乎肯定要快得多。它指出,你必须扔掉89%的计算值,所以在这里使用过滤器可能远远不是最佳的。它是有效的,但我认为正确的和是block_view(a)。sum(axis=(2,3))。顺便说一句,有没有一个很好的解释来解释人类在某个地方的“跨越式”呢?我花了很长时间想知道为什么这不起作用,结果发现sum()是用numpy 1.7更新的,axis=(1,3)在我的版本(1.6)中不起作用是的,你是对的。在早期版本中,您可以使用.sum(axis=3).sum(axis=1)
而不是.sum(axis=(1,3))
获得相同的结果。请注意,顺序很重要,即.sum(axis=1)。sum(axis=3)
将产生错误,因为在第一次求和之后,数组仅为3D,因此axis=3
超出范围。
>>> arr.reshape(rows//3, 3, cols//3, 3).sum(axis=(1, 3)) / 9
array([[ 13., 16., 19., 22.],
[ 49., 52., 55., 58.],
[ 85., 88., 91., 94.]])