I'm trying to achieve a similar goal to this question. The objective is to count the number of 1s with at least two direct neighbours (up, down, left, right), the only difference with my version is that there must be at least one cross or corner in the sequence.
For example,
array([[0, 0, 0, 0, 0, 1],
[0, 1,*1, 1, 0, 0],
[0, 0, 0, 0, 0, 0],
[1, 0, 0, 0, 0, 0],
[1, 1, 0, 1, 1, 0],
[1, 0, 0, 0, 1, 0]])
The starred *1 does not count as its neighbours do not form a corner or a cross. Nor does the top right 1 as it doesn't have two neighbours. The answer would be 2 (bottom right and left).
Here's what I tried:
import numpy as np
a = np.zeros((6,6), dtype=np.int)
a[0,5] = 1
a[1,1] = a[1,2] = a[1,3] = 1
a[4,4] = a[5,4] = a[4,3] = 1
a[3,0] = a[4,0] = a[5,0] = a[4,1] = 1
from scipy import ndimage
kernel = ndimage.generate_binary_structure(2, 1)
kernel[1, 1] = 0
b = convolve(a, kernel, mode="constant")
c = b[a>0]
# At least 2 neighbours
return len(c[c >= 2])
But it still counts the starred *1 from the second row (returns 3 instead of 2)!
Thanks for any help!
Your criterion can be restated "at least one neighbor horizontally and at least one neighbor vertically". So do whatever neighbor detection you'll end up choosing not in 2D but twice in 1D, once horizontally and once vertically:
For example, using
scipy.ndimage
which providesconvolve1d
:(
in_
is the example array in OP.)