猿问

NumPy - 从另一个 2d 数组中选择一个子矩阵

这是我的原始2d阵列A


[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],

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

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

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

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

 [0, 2, 2, 8, 8, 8, 2, 0, 0, 0],

 [0, 2, 2, 8, 8, 8, 2, 0, 0, 0],

 [0, 0, 0, 8, 8, 8, 0, 0, 0, 0],

 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],

 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]

假设我想在中间返回一个 8 的 3x3 子矩阵。我用这个表达式做了一个布尔面具,它看起来像这样。A == 8


array([[False, False, False, False, False, False, False, False, False,

        False],

       [False, False, False, False, False, False, False, False, False,

        False],

       [False, False, False, False, False, False, False, False, False,

        False],

       [False, False, False, False, False, False, False, False, False,

        False],

       [False, False, False, False, False, False, False, False, False,

        False],

       [False, False, False,  True,  True,  True, False, False, False,

        False],

       [False, False, False,  True,  True,  True, False, False, False,

        False],

       [False, False, False,  True,  True,  True, False, False, False,

        False],

       [False, False, False, False, False, False, False, False, False,

        False],

       [False, False, False, False, False, False, False, False, False,

        False]])

这就是我陷入困境的地方。如何返回带有该布尔掩码的子矩阵?如果我这样做,它会返回一个8s的平面数组,如下所示A[A == 8]


array([8, 8, 8, 8, 8, 8, 8, 8, 8])

另一种方法是获取返回 的行号和列号。如何使用它们返回矩阵?np.where(A == 8)(array([5, 5, 5, 6, 6, 6, 7, 7, 7]), array([3, 4, 5, 3, 4, 5, 3, 4, 5]))


对于这个问题,有没有更好的方法?


Helenr
浏览 142回答 3
3回答

泛舟湖上清波郎朗

如注释中所述,正确返回值的 rank-1 数组。这是有道理的,因为并不总是将值组织在一个块中(例如),或者值的数量使得它们不能放入2D数组中。A[A==some_value]some_valuesome_valuesome_value = 2some_value但是,如果您确定存在这样的块,则可以执行以下操作来获取它:import numpy as npinds = np.where(A==8)slice_x = slice(inds[0].min(), inds[0].max() + 1)  # slice(6, 9, None)slice_y = slice(inds[1].min(), inds[1].max() + 1)  # slice(3, 6, None)A[slice_x, slice_y]# array([[8, 8, 8],#        [8, 8, 8],#        [8, 8, 8]])作为替代方法,您可以使用 来获取切片:scipy.ndimage.find_objectsfrom scipy import ndimageslice_x, slice_y = ndimage.find_objects(A==8)[0]  # (slice(6, 9, None), slice(3, 6, None))

幕布斯6054654

您可以捕获和索引,然后仅使用np.ix_方法从这些索引返回子矩阵:rowcolumnx, y = np.where(A==8) #[5 5 5 6 6 6 7 7 7], [3 4 5 3 4 5 3 4 5]x, y = np.unique(x), np.unique(y) # [5,6,7], [3,4,5]print(A[np.ix_(x, y)]) #prints [[8 8 8], [8 8 8], [8 8 8]]即使在更一般的情况下,这也应该有效,尽管并不总是像预期的那样:def submatrix(A):    x, y = np.where(A==8)    x, y = np.unique(x), np.unique(y)    return A[np.ix_(x, y)]>>> A = np.array([[8, 2, 8, 2, 8, 0],[2, 8, 8, 8, 2, 0],[2, 8, 4, 8, 3, 0],[0, 8, 8, 8, 0, 0],[8, 0, 8, 0, 8, 0],[0, 0, 0, 0, 0, 0]])>>> submatrix(A)array([[8, 2, 8, 2, 8],       [2, 8, 8, 8, 2],       [2, 8, 4, 8, 3],       [0, 8, 8, 8, 0],       [8, 0, 8, 0, 8]])>>> A = np.array([[8, 2, 8, 2, 8, 0],[2, 2, 8, 8, 2, 0],[2, 2, 4, 3, 3, 0],[0, 2, 8, 8, 0, 0],[8, 0, 8, 0, 8, 0],[0, 0, 0, 0, 0, 0]])>>> submatrix(A) # skipping empty rows and columnsarray([[8, 8, 2, 8],       [2, 8, 8, 2],       [0, 8, 8, 0],       [8, 8, 0, 8]])由于返回排序数组,因此您可以填充构造的空白,如下所示:np.uniquexydef submatrix(A):    x, y = np.where(A==8)    x, y = np.unique(x), np.unique(y)    x, y = np.arange(x[0], x[-1]+1), np.arange(y[0], y[-1]+1)    return A[np.ix_(x, y)]

慕侠2389804

您可以尝试以下操作 data = A[np.any(A==8,axis=1)]  data.T[np.all(data==8,axis=0)]这应该给, array([[8, 8, 8],         [8, 8, 8],         [8, 8, 8]])
随时随地看视频慕课网APP

相关分类

Python
我要回答