Как изменить размер массива обрезав ненужные данные?
Есть массив:
arr = [[0, 0, 0,0, 0, 0,0, 0, 0],
[0, 0, 0,0, 0, 0,0, 0, 0],
[0, 0, 3,5, 6, 7,0, 0, 0],
[0, 1, 1,1, 1, 1,7, 0, 0],
[0, 7, 1,1, 1, 1,1, 7, 0],
[0, 7, 1,1, 1, 1,1, 7, 0],
[0, 7, 1,1, 1, 1,7, 0, 0],
[0, 0, 7,7, 7, 7,0, 0, 0],
[0, 0, 0,0, 0, 0,0, 0, 0],
[0, 0, 0,0, 0, 0,0, 0, 0],
[0, 0, 0,0, 0, 0,0, 0, 0],
[0, 0, 0,0, 0, 0,0, 0, 0],
[0, 0, 0,0, 0, 0,0, 0, 0],
[0, 0, 0,0, 0, 0,0, 0, 0]]
Надо получить что-то на подобие вот этого:
result_array = [[ 0, 3,5, 6, 7,0, 0, ],
[ 1, 1,1, 1, 1,7, 0, ],
[ 7, 1,1, 1, 1,1, 7, ],
[ 7, 1,1, 1, 1,1, 7, ],
[ 7, 1,1, 1, 1,7, 0, ],
[ 0, 7,7, 7, 7,0, 0, ]]
Задаю маску для поиска отсутствующих данных:
mask = arr==0
Как получить обрезанный массив без отсутствующих данных (=0)?
Ответы (4 шт):
Автор решения: slippyk
→ Ссылка
def v_trim_array(multi_array):
zero_index = None
for index in range(len(multi_array[0])):
flag = False
for array in multi_array:
if array[index]:
flag = True
if zero_index is not None:
array[zero_index] = array[index]
if flag:
zero_index += 1
else:
if zero_index is None:
zero_index = index
for array in reversed(multi_array):
del array[zero_index:]
def h_trim_array(multi_array):
zero_index = None
for index, array in enumerate(multi_array):
if any(array):
if zero_index is not None:
multi_array[zero_index] = array
zero_index += 1
else:
if zero_index is None:
zero_index = index
del multi_array[zero_index:]
multi_array = [
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 3, 5, 6, 7, 0, 0, 0],
[0, 1, 1, 1, 1, 1, 7, 0, 0],
[0, 7, 1, 1, 1, 1, 1, 7, 0],
[0, 7, 1, 1, 1, 1, 1, 7, 0],
[0, 7, 1, 1, 1, 1, 7, 0, 0],
[0, 0, 7, 7, 7, 7, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0]
]
# сначала убираем нулевые строки (по горизонтали)
h_trim_array(multi_array)
# затем убираем нулевые столбцы (по вертикали)
v_trim_array(multi_array)
for array in multi_array:
print(' '.join(map(str, array)))
# 0 3 5 6 7 0 0
# 1 1 1 1 1 7 0
# 7 1 1 1 1 1 7
# 7 1 1 1 1 1 7
# 7 1 1 1 1 7 0
# 0 7 7 7 7 0 0
Автор решения: mkkik
→ Ссылка
Конечно же можно использовать транспонирование через zip:
from pprint import pprint
arr = [[0, 0, 0,0, 0, 0,0, 0, 0],
[0, 0, 0,0, 0, 0,0, 0, 0],
[0, 0, 3,5, 6, 7,0, 0, 0],
[0, 1, 1,1, 1, 1,7, 0, 0],
[0, 7, 1,1, 1, 1,1, 7, 0],
[0, 7, 1,1, 1, 1,1, 7, 0],
[0, 7, 1,1, 1, 1,7, 0, 0],
[0, 0, 7,7, 7, 7,0, 0, 0],
[0, 0, 0,0, 0, 0,0, 0, 0],
[0, 0, 0,0, 0, 0,0, 0, 0],
[0, 0, 0,0, 0, 0,0, 0, 0],
[0, 0, 0,0, 0, 0,0, 0, 0],
[0, 0, 0,0, 0, 0,0, 0, 0],
[0, 0, 0,0, 0, 0,0, 0, 0]]
pprint(list(zip(*filter(any, zip(*filter(any, arr))))))
# [(0, 3, 5, 6, 7, 0, 0),
# (1, 1, 1, 1, 1, 7, 0),
# (7, 1, 1, 1, 1, 1, 7),
# (7, 1, 1, 1, 1, 1, 7),
# (7, 1, 1, 1, 1, 7, 0),
# (0, 7, 7, 7, 7, 0, 0)]
Немного поясненений:
filter(any, arr)- отсеиваем строки, состоящие из нулейzip(*filter(any, arr))- транспонируем матрицу из оставшихся строкfilter(any, zip(*filter(any, arr)))- аналогично первому пункту, но уже на транспонированной матрице (отсеиваем строки, которые раньше были столбцами)zip(*filter(any, zip(*filter(any, arr))))- транспонируем обратно
Автор решения: strawdog
→ Ссылка
Воспользуйтесь функционалом numpy:
import numpy as np
arr = np.array([[0, 0, 0,0, 0, 0,0, 0, 0],
[0, 0, 0,0, 0, 0,0, 0, 0],
[0, 0, 3,5, 6, 7,0, 0, 0],
[0, 1, 1,1, 1, 1,7, 0, 0],
[0, 7, 1,1, 1, 1,1, 7, 0],
[0, 7, 1,1, 1, 1,1, 7, 0],
[0, 7, 1,1, 1, 1,7, 0, 0],
[0, 0, 7,7, 7, 7,0, 0, 0],
[0, 0, 0,0, 0, 0,0, 0, 0],
[0, 0, 0,0, 0, 0,0, 0, 0],
[0, 0, 0,0, 0, 0,0, 0, 0],
[0, 0, 0,0, 0, 0,0, 0, 0],
[0, 0, 0,0, 0, 0,0, 0, 0],
[0, 0, 0,0, 0, 0,0, 0, 0]])
Сам код:
res = arr[~np.all(arr == 0, axis=1)]
res = res[:, ~np.all(res == 0, axis=0)]
print(res)
Результат:
[[0 3 5 6 7 0 0]
[1 1 1 1 1 7 0]
[7 1 1 1 1 1 7]
[7 1 1 1 1 1 7]
[7 1 1 1 1 7 0]
[0 7 7 7 7 0 0]]
Автор решения: MaxU
→ Ссылка
Можно воспользоваться методом numpy.nonzero(), возвращающим индексы ненулевых элементов по каждой размерности / оси:
nz = np.nonzero(arr)
res = arr[nz[0].min():nz[0].max()+1, nz[1].min():nz[1].max()+1]
результат:
In [19]: res
Out[19]:
array([[0, 3, 5, 6, 7, 0, 0],
[1, 1, 1, 1, 1, 7, 0],
[7, 1, 1, 1, 1, 1, 7],
[7, 1, 1, 1, 1, 1, 7],
[7, 1, 1, 1, 1, 7, 0],
[0, 7, 7, 7, 7, 0, 0]])