Ссылаясь на этот предыдущий вопрос:
Удалить все нулевые строки в 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]]
Здесь один подход -
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]])
Вы можете использовать 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]])