Как можно ускорить перебор массива?
Есть изображение 1752x1264 точек. Каждая точка содержит значение False или True.
Сейчас, чтобы получить массив, мы выполняем вот такой код:
for i in range(array.shape[0]):
for j in range(array.shape[1]):
if array[i][j] == True:
rect.append([[j,i]])
В среднем он выполняется 2-3 секунды.
Как можно ускорить его выполнение?
Ответы (2 шт):
Автор решения: strawdog
→ Ссылка
Попробуйте так (пример):
import numpy as np
a = np.array([[False, True, False],
[True, False, True]])
print(a) # исходный массив
print(np.argwhere(a==True)) # ваш результат
Соответственно выдаст:
[[False True False]
[ True False True]]
[[0 1]
[1 0]
[1 2]]
Автор решения: MaxU
→ Ссылка
Проще всего воспользоваться функцией np.nonzero().
пример исходной матрицы:
In [29]: a = np.random.choice([True, False], size=(5, 3))
In [30]: a
Out[30]:
array([[False, True, False],
[False, False, False],
[False, True, False],
[False, False, True],
[False, False, True]])
решение:
r_idx, c_idx = np.nonzero(a)
res = np.column_stack((c_idx, r_idx))
результат:
In [33]: res
Out[33]:
array([[1, 0],
[1, 2],
[2, 3],
[2, 4]], dtype=int64)
замеры времени выполнения:
In [46]: a = np.random.choice([True, False], size=(1752, 1264))
In [47]: %%timeit
...: res = np.argwhere(a == True)[:, ::-1]
...:
...:
44.6 ms ± 539 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
In [48]: %%timeit
...: r_idx, c_idx = np.nonzero(a)
...: res = np.column_stack((c_idx, r_idx))
...:
...:
42.7 ms ± 255 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
UPDATE: чтобы получить трехмерный массив как в вопросе:
res = res.reshape(res.shape[0], 1, -1)