I have a boolean array and I want to do a simple one-element binary dilation, that is, set to True
all elements inmediately adjacent to other True
elements.
arr=np.array([0,0,1,0,0,0,1,0,0], dtype=bool)
# array([False, False, True, False, False, False, True, False, False], dtype=bool)
# set elements before True to also True
arr[:-1] |= arr[1:]; arr
array([False, True, True, False, False, True, True, False, False], dtype=bool)
This worked just fine. The problem is when I want to set elements after True
to also True
arr[1:] |= arr[:-1]; arr
array([False, True, True, True, True, True, True, True, True], dtype=bool)
This result is wrong. Interestingly, when not done in-place, the last operation works just fine:
arr[1:] = arr[1:] | arr[:-1]; arr
array([False, True, True, True, False, True, True, True, False], dtype=bool)
I could not find out if boolean operators like &
or |
support in-place assigment. If they do, why is arr[1:] |= arr[:-1]
yielding the wrong result?
The result of such a slice assignment was undefined/buggy in numpy<1.13.0
. See the mention in the release notes here.
Operations where ufunc input and output operands have memory overlap produced undefined results in previous NumPy versions, due to data dependency issues. In NumPy 1.13.0, results from such operations are now defined to be the same as for equivalent operations where there is no memory overlap.
Upgrade your numpy version for the "correct" result.
Note that binary dilation is implemented directly in scipy:
>>> arr
array([False, False, True, False, False, False, True, False, False], dtype=bool)
>>> from scipy.ndimage.morphology import binary_dilation
>>> binary_dilation(arr)
array([False, True, True, True, False, True, True, True, False], dtype=bool)