【问题标题】:How can i remove the first n columns/lines with 0 values in a 2D matrix?如何删除二维矩阵中具有 0 值的前 n 列/行?
【发布时间】:2018-06-21 10:45:28
【问题描述】:

参考上一个问题:

Remove all-zero rows in a 2D matrix

import numpy as np

data = np.array([[4, 1, 1, 2, 0, 4],
                 [3, 4, 3, 1, 4, 4],
                 [1, 4, 3, 1, 0, 0],
                 [0, 4, 4, 0, 4, 3],
                 [0, 0, 0, 0, 0, 0]])

data = data[~(data==0).all(1)]
print(data)

输出:

    [[4 1 1 2 0 4]
     [3 4 3 1 4 4]
     [1 4 3 1 0 0]
     [0 4 4 0 4 3]]

到目前为止还不错,但是如果我添加空列怎么办?

 data = np.array([[0, 4, 1, 1, 2, 0, 4],
                  [0, 3, 4, 3, 1, 4, 4],
                  [0, 0, 1, 4, 3, 1, 0],
                  [0, 0, 4, 4, 0, 4, 3],
                  [0, 0, 0, 0, 0, 0, 0]])

输出是

          [[0 4 1 1 2 0 4]
           [0 3 4 3 1 4 4]
           [0 1 4 3 1 0 0]
           [0 0 4 4 0 4 3]]

这不是我想要的。

如果我的矩阵是:

            [[0, 0, 0, 0, 0, 0, 0, 0, 0],
             [0, 0, 4, 1, 1, 2, 0, 4, 0],
             [0, 0, 3, 4, 3, 1, 4, 4, 0],
             [0, 0, 1, 4, 3, 1, 0, 0, 0],
             [0, 0, 0, 4, 4, 0, 4, 3, 0],
             [0, 0, 0, 0, 0, 0, 0, 0, 0]]

我期待的输出是

        [[4 1 1 2 0 4]
         [3 4 3 1 4 4]
         [1 4 3 1 0 0]
         [0 4 4 0 4 3]]

【问题讨论】:

  • 如果中间有空行或列怎么办?
  • 它们应该保持不变。

标签: python numpy


【解决方案1】:

这是一种方法 -

def reduced_box(a):
    # Store shape info
    M,N = a.shape

    # Mask of valid places in the array
    mask = a!=0

    # Get boolean array with at least a valid one per row
    m_col = mask.any(1)

    # Get the starting and ending valid rows with argmax.
    # More info : https://stackoverflow.com/a/47269413/
    r0,r1 = m_col.argmax(), M-m_col[::-1].argmax()

    # Repeat for cols
    m_row = mask.any(0)
    c0,c1 = m_row.argmax(), N-m_row[::-1].argmax()

    # Finally slice with the valid indices as the bounding box limits
    return a[r0:r1,c0:c1]

示例运行 -

In [210]: a
Out[210]: 
array([[0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 4, 1, 0, 2, 0, 4, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 1, 4, 0, 1, 0, 0, 0],
       [0, 0, 0, 4, 0, 0, 4, 3, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0]])

In [211]: reduced_box(a)
Out[211]: 
array([[4, 1, 0, 2, 0, 4],
       [0, 0, 0, 0, 0, 0],
       [1, 4, 0, 1, 0, 0],
       [0, 4, 0, 0, 4, 3]])

【讨论】:

  • 工作并被接受,你能解释一下代码吗?
  • @Nelly 添加了 cmets。
【解决方案2】:

你可以使用scipy.ndimage.measurements.find_objects:

import numpy as np
from scipy.ndimage.measurements import find_objects

data = np.array([[0, 0, 0, 0, 0, 0, 0, 0, 0],
                 [0, 0, 4, 1, 1, 2, 0, 4, 0],
                 [0, 0, 3, 4, 3, 1, 4, 4, 0],
                 [0, 0, 1, 4, 3, 1, 0, 0, 0],
                 [0, 0, 0, 4, 4, 0, 4, 3, 0],
                 [0, 0, 0, 0, 0, 0, 0, 0, 0]])
data[find_objects(data.astype(bool))[0]]
#array([[4, 1, 1, 2, 0, 4],
#       [3, 4, 3, 1, 4, 4],
#       [1, 4, 3, 1, 0, 0],
#       [0, 4, 4, 0, 4, 3]])

【讨论】:

  • 我以前没见过这个功能,整洁。
猜你喜欢
  • 1970-01-01
  • 2021-09-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-10
  • 2013-09-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多