如何获得没有numpy的2D数组的所有子矩阵?

时间:2017-05-22 11:02:40

标签: arrays python-3.x loops matrix submatrix

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

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列然后移动这个“窗口”直到我得到所有子矩阵。第一个子矩阵将是:

 [[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的情况下获得2D数组的所有子矩阵?

2 个答案:

答案 0 :(得分:2)

您的代码正在运行(更改变量和常量的顺序):

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)

答案 1 :(得分:1)

我会解决它略有不同。 读取y行数的函数 然后是一个从这些行读取x-number-of-columns的函数,然后是你的子。

这适用于任何(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)

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