在一个大矩阵中迭代子矩阵

3
我希望能够通过使用for循环来遍历一个更大的矩阵,并在每次迭代时输出一个大小为(6,3,3)的子矩阵。
我的大矩阵存储为numpy矩阵,我也希望每次迭代都能以这种方式输出。
>>> import numpy as np
>>> a = np.random.rand(6*3,3*3,3)
>>> print a.shape
(18, 9, 3)
>>> print a
>>> b

变量b应包含矩阵a中大小为(6,3,3)的所有子矩阵。 每个子矩阵不应与先前的重叠。

enter image description here


你正在寻找滑动矩阵吗?输入数组有多少个维度?能否添加一个示例案例? - Divakar
是的...我想你可以称它为一个滑动矩阵。维度嘛,行总是78(可被6整除)。列取决于数据长度,但总是可被3整除,深度为3(实际上是4个RGBA,但我正在去除alpha通道)。 - J.Down
那么,你从刚刚编辑的样本数据中应该得到多少个这样的子矩阵? - Divakar
哦,抱歉...等一下。我编辑了上面的帖子。 现在...它是正确的...应该是9个子矩阵。输入形状将始终具有深度3。子矩阵不能重叠。 - J.Down
我猜我们对“滑动”这个术语不是很清楚。所以,让我换一个不同的术语——我们是在寻找沿着输入数组的三个维度滑动的重叠块还是不同的块? - Divakar
显示剩余4条评论
1个回答

2

方法 #1

我假设我们正在寻找非重叠/不同的块。因此,我们可以使用Scikit-image的view_as_blocks工具 -

from skimage.util.shape import view_as_blocks

BSZ = (6,3,3)
out = view_as_blocks(a,BSZ).reshape((-1,)+ (BSZ))

样例运行 -

In [279]: a = np.random.rand(6*3,3*3,3)

In [280]: out = view_as_blocks(a,BSZ).reshape((-1,)+ (BSZ))

In [281]: out.shape
Out[281]: (9, 6, 3, 3)

方法二

只使用NumPy原生工具,如重塑(reshaping)转置(transpose),以下是一种方式 -

m,n,r = a.shape
split_shp = m//BSZ[0], BSZ[0], n//BSZ[1], BSZ[1], r//BSZ[2], BSZ[2]
out = a.reshape(split_shp).transpose(0,2,4,1,3,5).reshape((-1,)+ (BSZ))

有什么我应该担心的吗? - J.Down
如警告消息所述,我猜测您的输入不是连续的,这取决于输入源。因此,为了安全起见,我认为您可以选择第二个应用程序,因为内部第一个应用程序正在做类似的事情。 - Divakar
out = matrix.reshape(split_shp).transpose(0,2,4,1,3,5).reshape((-1,)+ (BSZ)) ValueError: total size of new array must be unchanged - J.Down
1
啊,是的,我得修复一些东西... 我更喜欢方法1而不是方法2,因为它更易读。能否让它更易读一些? - J.Down
@J.Down 嗯,我认为那是我能做到的最好的了 :) - Divakar
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接