Какой самый питонический способ найти все пары координат в массиве numpy, которые соответствуют определенному условию? - PullRequest
2 голосов
/ 19 июня 2019

Таким образом, учитывая двумерный массив, состоящий из единиц и нулей, я хочу найти каждый индекс, где он имеет значение, равное одному и , где либо его верхняя, левая, правая или нижняя часть состоит из нуль. Например, в этом массиве

0 0 0 0 0   
0 0 1 0 0   
0 1 1 1 0  
0 0 1 0 0  
0 0 0 0 0  

Мне нужны координаты только для (1,2), (2,1), (2,3) и (3,2) , но не для (2,2).

Я создал код, который работает и создает два списка координат, аналогично методу NumPy, отличному от нуля, однако я не думаю, что он очень "питонический", и я надеялся, что есть лучший и более эффективный способ решения этой проблемы , (* Обратите внимание, что это работает только для массивов, дополненных нулями)

from numpy import nonzero
...
array= ... # A numpy array consistent of zeros and ones
non_zeros_pairs=nonzero(array)
coordinate_pairs=[[],[]]
for x, y in zip(temp[0],temp[1]):
    if array[x][y+1]==0 or array[x][y-1]==0 or array[x+1][y]==0 or array[x-1][y]==0:
             coordinate_pairs[0].append(x)
             coordinate_pairs[1].append(y)
...

Если бы в numpy были методы, которые могли бы справиться с этим для меня, это было бы замечательно. Если этот вопрос уже задавался / отвечал на stackoverflow прежде, я с радостью удалю это, я просто пытался найти что-нибудь. Спасибо.

1 Ответ

3 голосов
/ 19 июня 2019

Настройка

import scipy.signal
import numpy as np

a = np.array([[0, 0, 0, 0, 0],
              [0, 0, 1, 0, 0],
              [0, 1, 1, 1, 0],
              [0, 0, 1, 0, 0],
              [0, 0, 0, 0, 0]])

Создайте окно, которое соответствует четырем направлениям от каждого значения, и convolve.Затем вы можете проверить, являются ли элементы 1 и их свертка меньше 4, поскольку значение ==4 означает, что значение было окружено 1s

window = np.array([[0, 1, 0],
                   [1, 0, 1],
                   [0, 1, 0]])

m = scipy.signal.convolve2d(a, window, mode='same', fillvalue=1)

v = np.where(a & (m < 4))

list(zip(*v))

[(1, 2), (2, 1), (2, 3), (3, 2)]
...