2014-10-30 3 views
2

Я начинаю с логического массива nxm, который определяет области - true, если он находится в области, false, если нет. Например:2D numpy array - проверить, равны ли все соседние термины

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

Граница между регионами может быть определено как п-1 х м-1 массив, который будет представлять собой «точку» между каждым набором из четырех значений. Если все 4 окружающих значения одинаковы, вы не находитесь на грани между регионами. Если какое-либо из 4 значений отличается, вы. Для r выше:

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

Любые мысли о том, как это можно сделать эффективно? Я попытался сделать diff в обоих направлениях, но это удваивается. Есть ли функция двумерного разложения? Какой-то другой способ сделать это?

ответ

5

Это будет делать тест на точек окруженную True,

tmp = r[1:] & r[:-1] 
l = np.logical_not(tmp[:, 1:] & tmp[:, :-1]) 

Затем вы можете сделать тест на точек окруженных False таким же образом и объединить их,

r = np.logical_not(r) 
tmp = r[1:] & r[:-1] 
l &= np.logical_not(tmp[:, 1:] & tmp[:, :-1]) 

print l.astype(int) 
# [[1 1 1 1] 
# [1 0 1 1] 
# [1 0 1 1] 
# [0 1 1 0]] 
+0

Это не дает правильного результата в '[3,3]'. – tom10

+0

Я заметил, что я это исправил. Благодаря! – farenorth

+1

+1 с исправлением, и вопрос был бы лучше, если бы этот пример был правильным синтаксисом и проще тестировать. – tom10

2

Хороший ответ уже выбран, но мне нравятся решения, которые легко писать и понимать, поэтому я все равно опубликую это:

from scipy.signal import convolve2d 
kernel = np.array(((1, 1), (1, 1))) 

x = convolve2d(r, kernel, mode="valid") # sum all the neighboring values (and mode handles the boundary issues) 
x[x==4] = 0        # set the elements that sum to 4 to zero (the ones that sum to 0 are already 0) 
x[x>0] = 1        # anything greater than one is set to 1 

[[1 1 1 1] 
[1 0 1 1] 
[1 0 1 1] 
[0 1 1 0]] 
+0

Да/+ 1, мне нравится этот b/c, конечно, читать легче. Поскольку мне было любопытно, я провела некоторые тесты скорости. Мое решение на массиве примеров на 30% быстрее и * намного быстрее, когда массивы становятся больше. ;) – farenorth

+0

@farenorth: наверняка, вероятно, из-за всех умножений. – tom10

Смежные вопросы