Как я могу удалить первые n столбцов / строк с 0 значениями в 2D матрице?

1

Ссылаясь на этот предыдущий вопрос:

Удалить все нулевые строки в 2D-матрице

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]]
Теги:
numpy

2 ответа

2
Лучший ответ

Здесь один подход -

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]])
  • 0
    Работает и принято, не могли бы вы объяснить код, хотя.
  • 0
    @Nelly Добавлены комментарии.
1

Вы можете использовать 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]])
  • 0
    Я не видел эту функцию раньше, аккуратно.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню