python - numpy 数组的固定大小子矩阵的索引

标签 python arrays numpy

我正在实现一种算法,该算法要求我查看(严格来说是二维的)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/

相关文章:

python - 如何将 cv::Mat 转换为 python

java - 使用扫描仪和异常读取文本文件中的整数并存储到数组

python - 如何将累积数据转换为每日数据?

python Pandas : split a data frame based on a column value

Python 生成器和文件对象

php - 用 str_split() 替换 expand() 的使用

javascript - 如何访问另一个数组中的对象数组中的 ID 或名称?

python - 相当于在 Tensorflow 中设置类似 Numpy 的掩码值?

python - 计算两点之间的逆时针角度

python - 扫描txt,将某些数据 append 到Python中的空列表