根据它们在矩阵中的位置将二维 numpy 数组中的零值坐标分组到列表中

Grouping coordinates of zero values in a 2D numpy array into lists based on their position in the matrix

排除边界零值,是否可以将剩余零值的坐标(作为元组)分组到此 numpy 数组中的不同列表中?

[[ 0  0  0  0  0  0  0  0  0  0  0]
 [ 0  1  1  1  0  0  0  1 10  2  0]
 [ 0  2 10  2  1  0  0  1  2 10  0]
 [ 0 10  3 10  1  0  0  0  1  1  0]
 [ 0  1  2  1  1  0  0  0  0  0  0]
 [ 0  1  2  1  2  2  2  1  0  0  0]
 [ 0 10  2 10  2 10 10  1  0  0  0]
 [ 0  1  2  1  2  2  2  1  1  1  0]
 [ 0  0  0  0  0  0  0  0  1 10  0]
 [ 0  0  0  0  0  0  0  0  1  1  0]
 [ 0  0  0  0  0  0  0  0  0  0  0]]

例如。在上面的网格中,有两个 'groups' 个零,一个在左下角,另一个在右上角。对于生成的每个这样的矩阵,这些可以放入单独的列表中吗?下面是创建矩阵 'sol_mat' 的代码:-

import numpy as np
import random

bomb_mat = np.zeros((11,11), dtype = int)
for i in range(10):
    a = random.randint(1,9)
    b = random.randint(1,9)
    bomb_mat[a,b] = 1

sol_mat = np.zeros(11,11), dtype = int)
for j in range(1,10):
    for k in range(1,y-1):
        if bomb_mat[j,k] == 1:
            sol_mat[j,k] = 10
        else:
            sol_mat[j,k] = bomb_mat[j-1,k-1] + bomb_mat[j,k-1] + bomb_mat[j+1,k-1]+ bomb_mat[j-1,k] + bomb_mat[j+1,k] + bomb_mat[j-1,k+1] + bomb_mat[j,k+1] + bomb_mat[j+1,k+1]

正在尝试创建扫雷

我对你的代码做了一些调整。主要是我试图避免 for 循环,我使用 scipys convolve2d() 来创建 sol_mat。这种方法的主要优点是您不必担心图像的边缘情况。在炸弹的布尔数组上使用 ones3x3 kernel 可以准确计算出相邻炸弹的数量(扫雷器中的旗帜)。

import numpy as np
from scipy.signal import convolve2d

grid_size = (7, 7)
n_bombs = 5

bomb_mat = np.zeros(grid_size, dtype=int)
bomb_mat[np.random.randint(low=1, high=grid_size[0]-1, size=n_bombs),
         np.random.randint(low=1, high=grid_size[1]-1, size=n_bombs)] = 1
# array([[0, 0, 0, 0, 0, 0, 0],
#        [0, 0, 0, 0, 1, 0, 0],
#        [0, 0, 1, 0, 0, 0, 0],
#        [0, 1, 1, 0, 0, 0, 0],
#        [0, 0, 0, 0, 0, 0, 0],
#        [0, 0, 1, 0, 0, 0, 0],
#        [0, 0, 0, 0, 0, 0, 0]])

sol_mat = convolve2d(bomb_mat, np.ones((3, 3)), mode='same').astype(int)
sol_mat[bomb_mat.astype(bool)] = 10
# array([[ 0,  0,  0,  1,  1,  1,  0],
#        [ 0,  1,  1,  2, 10,  1,  0],
#        [ 1,  3, 10,  3,  1,  1,  0],
#        [ 1, 10, 10,  2,  0,  0,  0],
#        [ 1,  3,  3,  2,  0,  0,  0],
#        [ 0,  1, 10,  1,  0,  0,  0],
#        [ 0,  1,  1,  1,  0,  0,  0]])

您可以使用np.tril()np.triu() 来获取数组的下三角和上三角。通过使用条件 sol_mat == 0 构建布尔三角形的交集,您可以获得所需的索引:

lower0 = np.logical_and(np.tril(np.ones(grid_size)), sol_mat == 0)
# lower0.astype(int)
# array([[1, 0, 0, 0, 0, 0, 0],
#        [1, 0, 0, 0, 0, 0, 0],
#        [0, 0, 0, 0, 0, 0, 0],
#        [0, 0, 0, 0, 0, 0, 0],
#        [0, 0, 0, 0, 1, 0, 0],
#        [1, 0, 0, 0, 1, 1, 0],
#        [1, 0, 0, 0, 1, 1, 1]])
upper0 = np.logical_and(np.triu(np.ones(grid_size)), sol_mat == 0)
# upper0.astype(int)
# array([[1, 1, 1, 0, 0, 0, 1],
#        [0, 0, 0, 0, 0, 0, 1],
#        [0, 0, 0, 0, 0, 0, 1],
#        [0, 0, 0, 0, 1, 1, 1],
#        [0, 0, 0, 0, 1, 1, 1],
#        [0, 0, 0, 0, 0, 1, 1],
#        [0, 0, 0, 0, 0, 0, 1]])

您可以通过np.nonzero():

获取这些数组的索引
lower0_idx = np.array(np.nonzero(lower0))
# array([[0, 1, 4, 5, 5, 5, 6, 6, 6, 6],
#        [0, 0, 4, 0, 4, 5, 0, 4, 5, 6]])
upper0_idx = np.array(np.nonzero(upper0))
# array([[0, 0, 0, 0, 1, 2, 3, 3, 3, 4, 4, 4, 5, 5, 6],
#        [0, 1, 2, 6, 6, 6, 4, 5, 6, 4, 5, 6, 5, 6, 6]])