如何在没有numpy的情况下获取二维数组的所有子矩阵?

How to get all sub matrices of 2D array without numpy?

我需要获取二维数组的所有子矩阵并对每个子矩阵进行操作。所以我创建了示例矩阵:

M3 = [list(range(5)) for i in range(6)]
[[0, 1, 2, 3, 4],
 [0, 1, 2, 3, 4],
 [0, 1, 2, 3, 4],
 [0, 1, 2, 3, 4],
 [0, 1, 2, 3, 4],
 [0, 1, 2, 3, 4]]

我需要捕获 3 行和 3 列,然后移动这个 "window" 直到我得到所有子矩阵。第一个子矩阵是:

 [[0, 1, 2],
 [0, 1, 2],
 [0, 1, 2]]

最后一个是:

 [[2, 3, 4],
 [2, 3, 4],
 [2, 3, 4]]

对于这个矩阵,我需要 12 个子矩阵。但是,我越来越多地使用尝试解决问题的代码:

for j in range(len(M3[0])-3):
   for i in range(len(M3)-3):
       for row in M3[0+j:3+j]:
           X_i_j = [row[0+i:3+i] for row in M3[0+j:3+j]]
           print(X_i_j)

我得到 18 而不是 12(每个子矩阵有两个副本):

[[0, 1, 2], [0, 1, 2], [0, 1, 2]]
[[0, 1, 2], [0, 1, 2], [0, 1, 2]]
[[0, 1, 2], [0, 1, 2], [0, 1, 2]]
[[1, 2, 3], [1, 2, 3], [1, 2, 3]]
[[1, 2, 3], [1, 2, 3], [1, 2, 3]]
[[1, 2, 3], [1, 2, 3], [1, 2, 3]]
...
[[2, 3, 4], [2, 3, 4], [2, 3, 4]]
[[2, 3, 4], [2, 3, 4], [2, 3, 4]]

通过这段代码示例,我得到了 6 个子矩阵,每个子矩阵有 1 个重复:

for i in range(len(M3)-3):
   for j in range(len(M3[0])-3):
       X_i_j = [row[0+i:3+i] for row in M3[0+j:3+j]]
       print(X_i_j)

我不明白它有什么问题以及为什么我得到重复项。对于这种情况,如何在没有 numpy 的情况下获取二维数组的所有子矩阵?

您的代码有效(改变了变量和常量的顺序):

for j in range(len(M3)-2):
for i in range(len(M3[0])-2):
   X_i_j = [row[0+i:3+i] for row in M3[0+j:3+j]]
   print('=======')
   for x in X_i_j:
       print(x)

我会稍微不同地解决它。 读取 y 行数的函数 然后是一个从这些行中读取 x 列的函数,这就是你的子项。

这适用于任何 (2D) 阵列/子阵列

样本:

def read_y_rows(array, rows, offset):
    return array[offset:rows + offset]


def read_x_cols(array, cols, offset):
    return list(row[offset:cols + offset] for row in array)


def get_sub_arrays(array, x_dim_cols, y_dim_rows):
    """
    get 2D sub arrays by x_dim columns and y_dim rows
    from 2D array (list of lists)
    """
    result = []
    for start_row in range(len(array) - y_dim_rows + 1):
        y_rows = read_y_rows(array, y_dim_rows, start_row)
        for start_col in range(len(max(array, key=len)) - x_dim_cols + 1):
            x_columns = read_x_cols(y_rows, x_dim_cols, start_col)
            result.append(x_columns)
    return result

要使用它,您可以这样做:

M3 = [list(range(5)) for i in range(6)]
sub_arrays = get_sub_arrays(M3, 3, 3) ## this would also work for 2x2 arrays

sub_arrays 又是一个列表列表,包含所有找到的子数组,你可以这样打印它们:

for sub_array in sub_arrays:
    print()
    for row in sub_array:
        print(row)

我知道它比上面的代码多很多,只是想分享这段代码。