首页 > 解决方案 > 奇怪的行为布尔就地操作

问题描述

我有一个布尔数组,我想做一个简单的单元素二进制膨胀,即设置为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)

这工作得很好。问题是当我想在 to 之后设置元素TrueTrue

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]产生错误的结果?

标签: pythonpython-3.xnumpyboolean-operations

解决方案


这种切片分配的结果是 undefined/buggy in numpy<1.13.0. 请参阅此处的发行说明中的​​提及。

由于数据依赖性问题,ufunc 输入和输出操作数具有内存重叠的操作在以前的 NumPy 版本中产生了未定义的结果。在 NumPy 1.13.0 中,此类操作的结果现在被定义为与没有内存重叠的等效操作相同。

升级你的 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)

推荐阅读