我正在实现一种算法,该算法要求我查看(严格来说是二维的)numpy 数组中的非重叠连续子矩阵。例如,对于 12 x 12
>>> a = np.random.randint(20, size=(12, 12)); a
array([[ 4, 0, 12, 14, 3, 8, 14, 12, 11, 18, 6, 6],
[15, 13, 2, 18, 15, 15, 16, 2, 9, 16, 6, 4],
[18, 18, 3, 8, 1, 15, 14, 13, 13, 13, 7, 0],
[ 1, 9, 3, 6, 0, 4, 3, 15, 0, 9, 11, 12],
[ 5, 15, 5, 6, 4, 4, 18, 13, 10, 17, 11, 8],
[13, 17, 8, 15, 17, 12, 7, 1, 13, 15, 0, 18],
[ 2, 1, 11, 12, 3, 16, 11, 9, 10, 15, 4, 16],
[19, 11, 10, 7, 10, 19, 7, 13, 11, 9, 17, 8],
[14, 14, 17, 0, 0, 0, 11, 1, 10, 14, 2, 7],
[ 6, 15, 6, 7, 15, 19, 2, 4, 6, 16, 0, 3],
[ 5, 10, 7, 5, 0, 8, 5, 8, 9, 14, 4, 3],
[17, 2, 0, 3, 15, 10, 14, 1, 0, 7, 16, 2]])
并查看 3x3 子矩阵,我希望第一个 3x3 子矩阵来自左上角:
>>> a[0:3, 0:3]
array([[ 4, 0, 12],
[15, 13, 2],
[18, 18, 3]])
接下来由 a[0:3, 3:6]
给出,依此类推。每行或列中的最后一组这样的索引是否超出数组的末尾并不重要 - numpy 的行为只是给出切片中存在的部分就足够了。
我想要一种以编程方式为任意大小的矩阵和子矩阵生成这些切片索引的方法。我目前有这个:
size = 3
x_max = a.shape[0]
xcoords = range(0, x_max, size)
xcoords = zip(xcoords, xcoords[1:])
类似地生成y_coords
,因此索引系列由itertools.product(xcoords, ycoords)
给出。
我的问题是:是否有更直接的方法来做到这一点,也许使用 numpy.mgrid
还是其他一些 numpy 技术?
最佳答案
获取索引
这是获取特定 size x size
block 的快速方法:
base = np.arange(size) # Just the base set of indexes
row = 1 # Which block you want
col = 0
block = a[base[:, np.newaxis] + row * size, base + col * size]
如果您愿意,您可以建立类似于您的xcoords
的矩阵,例如:
y, x = np.mgrid[0:a.shape[0]/size, 0:a.shape[1]/size]
y_coords = y[..., np.newaxis] * size + base
x_coords = x[..., np.newaxis] * size + base
然后你可以像这样访问一个 block :
block = a[y_coords[row, col][:, np.newaxis], x_coords[row, col]]
直接获取 block
如果您只想获取 block (而不是 block 条目的索引),我会使用 np.split
(两次):
blocks = map(lambda x : np.split(x, a.shape[1]/size, 1), # Split the columns
np.split(a, a.shape[0]/size, 0)) # Split the rows
然后你有一个 size x size
block 的二维列表:
>>> blocks[0][0]
array([[ 4, 0, 12],
[15, 13, 2],
[18, 18, 3]])
>>> blocks[1][0]
array([[ 1, 9, 3],
[ 5, 15, 5],
[13, 17, 8]])
然后您可以将其设为一个 numpy 数组并使用与上面相同的索引样式:
>>> blocks = np.array(blocks)
>>> blocks.shape
(4, 4, 3, 3)
关于python - numpy 数组的固定大小子矩阵的索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16713991/