奇怪的行为布尔就地操作

Odd behaviour boolean in-place operations

我有一个布尔数组,我想做一个简单的单元素二元膨胀,即将所有元素设置为 True 紧邻其他 True 个元素。

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)

这工作得很好。问题是当我想将 True 之后的元素也设置为 True

arr[1:] |= arr[:-1]; arr
array([False,  True,  True,  True,  True,  True,  True,  True,  True], dtype=bool)

这个结果是错误的。有趣的是,当没有就地完成时,最后一个操作工作得很好:

arr[1:] = arr[1:] | arr[:-1]; arr
array([False,  True,  True,  True, False,  True,  True,  True, False], dtype=bool)

我无法确定 &| 等布尔运算符是否支持就地赋值。如果他们这样做了,为什么 arr[1:] |= arr[:-1] 会产生错误的结果?

这种切片分配的结果是 numpy<1.13.0 中的 undefined/buggy。请参阅发行说明 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.

为 "correct" 结果升级你的 numpy 版本。

注意二元膨胀直接在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)