Numpy布尔数组上的布尔运算符之和(Bug?)

4

在使用numpyarray时,我遇到了一个令人惊讶的情况。以下是代码:

(True==True)+(True==True)

返回2,正如我们所期望的那样。然而,
import numpy
Array=numpy.zeros((2,2),dtype=bool)
(Array[0][0]==Array[0][0])+(Array[1][0]==Array[1][0])

返回 True。这将导致:

(Array[0][0]==Array[0][0])+(Array[1][0]==Array[1][0])-1

返回 0,同时

(Array[0][0]==Array[0][0])-1+(Array[1][0]==Array[1][0])

返回1,使得和不可交换!

这是有意为之吗?如果是,为什么呢?

2个回答

4

看起来 numpy.bool_ 的行为与普通的 Python bool 稍有不同:

>>> int(True+True) == int(True) + int(True)
True
>>> int(numpy.bool_(1)+numpy.bool_(1)) == int(numpy.bool_(1)) + int(numpy.bool_(1))
False

这是因为:
>>> True+True
2
>>> numpy.bool_(1)+numpy.bool_(1)
True
>>> int(numpy.bool_(1)+numpy.bool_(1))
1

基本上,对于 numpy.bool_ 类型的加法操作是逻辑操作,而不是数值操作;如果要使用 bool 实现相同的行为:

>>> int(True and True)
1

如果您只在需要真值的情况下使用它,那么这是可以的,但是如果您试图在整数上下文中使用它而没有明确指出,那么就会感到惊讶。一旦您明确指出,就能恢复预期的行为:

>>> int(numpy.bool_(1)) + int(numpy.bool_(1))
2

你知道为什么Numpy的布尔值被设计成与普通布尔值不同吗?或者普通布尔值中的布尔值求和也没有意图吗? 也许没有人考虑过这个问题^^ - Tilman
我不知道,没有。如果您感兴趣,可以在这里讨论是否删除这些运算符:https://www.mail-archive.com/numpy-discussion%40scipy.org/msg43366.html。 - jonrsharpe
谢谢你的回答,这激励我写出更干净、更漂亮的 Python 代码。尤其是在看到所有其他我没有注意到的问题之后(也许永远不会注意到)。 - Tilman

1
我认为问题在于自动转换。
在这种情况下:
(Array[0][0]==Array[0][0])+(Array[1][0]==Array[1][0])-1
Python do:
(Array[0][0]==Array[0][0])+(Array[1][0]==Array[1][0]) = True
True -1 =cast= 1 -1 = 0

在第二种情况中,转换是在之前执行的。
(Array[0][0]==Array[0][0])-1+(Array[1][0]==Array[1][0])
True - 1 + True 
(True - 1 =cast= 0)
0 + True =cast again=  0+ 1 = 1

所以,这不是一个 bug。它是在不同部分自动转换的结果。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接