Numpy:如何从矩阵的非零索引中提取元素形成子矩阵?

4
我有非常稀疏的矩阵,因此我想提取具有非零值的最小矩形区域。我知道numpy.nonzero(a)可以给出非零元素的索引,但是如何使用它来提取包含这些索引处矩阵元素的子矩阵呢?
举个例子,这就是我的目标:
>>> test
array([[0, 0, 0, 0, 0, 0],
       [0, 1, 1, 1, 1, 0],
       [0, 0, 1, 1, 0, 0]])
>>> np.nonzero(test)
(array([1, 1, 1, 1, 2, 2]), array([1, 2, 3, 4, 2, 3]))
>>> submatrix(test)
array([[1, 1, 1, 1],
       [0, 1, 1, 0]])

有人知道在numpy中简单实现这个的方法吗?谢谢。

1
你的示例输出和描述并不完全相同 - 你想提取矩阵的所有非零元素,还是想获取一个矩阵,该矩阵代表包含所有非零元素的原始矩阵的最小矩形区域? - Brionius
抱歉。是的,我确实想要最小的矩形区域,我应该表达得更清楚;我会进行编辑。 - user2909415
1个回答

6

看起来你想找到包含所有非零元素的最小矩阵区域。如果是这样,以下是一种方法:

import numpy as np

def submatrix(arr):
    x, y = np.nonzero(arr)
    # Using the smallest and largest x and y indices of nonzero elements, 
    # we can find the desired rectangular bounds.  
    # And don't forget to add 1 to the top bound to avoid the fencepost problem.
    return arr[x.min():x.max()+1, y.min():y.max()+1]

test = np.array([[0, 0, 0, 0, 0, 0],
                 [0, 1, 1, 1, 1, 0],
                 [0, 0, 1, 1, 0, 0]])

print submatrix(test)

# Result:  
# [[1 1 1 1]
#  [0 1 1 0]]

谢谢。非常好的解决方案,我承认我原本想到了一种更复杂的解决方案,这也是我先提出问题的原因。 - user2909415
应该是 y, x = np.nonzero(arr) 吧?这不会改变函数的结果(如果我们在返回语句中交换名称),但可以使代码更清晰(名称与轴顺序一致)。 - majkel.mk
@majkel.mk 你说得对,我总是对行、列、轴的顺序感到困惑。直觉上,我会认为在切片符号中,'x' 应该是第一个坐标,而 'y' 应该是第二个,因为这是数学/几何中的约定,但我也可以被说服它应该是另一种方式... - Brionius

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接