为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Helenr 2022-08-02 10:34:30
这是我的原始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 == 8array([[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]))对于这个问题,有没有更好的方法?
查看完整描述

3 回答

?
泛舟湖上清波郎朗

TA贡献1818条经验 获得超3个赞

如注释中所述,正确返回值的 rank-1 数组。这是有道理的,因为并不总是将值组织在一个块中(例如),或者值的数量使得它们不能放入2D数组中。A[A==some_value]some_valuesome_valuesome_value = 2some_value


但是,如果您确定存在这样的块,则可以执行以下操作来获取它:


import numpy as np


inds = 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_objects


from scipy import ndimage


slice_x, slice_y = ndimage.find_objects(A==8)[0]  # (slice(6, 9, None), slice(3, 6, None))


查看完整回答
反对 回复 2022-08-02
?
幕布斯6054654

TA贡献1876条经验 获得超7个赞

您可以捕获和索引,然后仅使用np.ix_方法从这些索引返回子矩阵:rowcolumn


x, 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 columns

array([[8, 8, 2, 8],

       [2, 8, 8, 2],

       [0, 8, 8, 0],

       [8, 8, 0, 8]])

由于返回排序数组,因此您可以填充构造的空白,如下所示:np.uniquexy


def 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)]


查看完整回答
反对 回复 2022-08-02
?
慕侠2389804

TA贡献1719条经验 获得超6个赞

您可以尝试以下操作

 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]])


查看完整回答
反对 回复 2022-08-02
  • 3 回答
  • 0 关注
  • 141 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信