python numpy奇怪的布尔算术行为

时间:2016-06-08 08:35:29

标签: python numpy boolean

为什么会这样,在python / numpy中:

from numpy import asarray
bools=asarray([False,True])

print(bools)
[False True]

print(1*bools, 0+bools, 0-bools)    # False, True are valued as 0, 1
[0 1] [0 1] [ 0 -1]

print(-2*bools, -bools*2)           # !? expected same result!  :-/
[0 -2] [2 0] 

print(-bools)                       # this is the reason!
[True False]

我认为-bools返回logical_not(bools)很奇怪,因为在所有其他情况下,行为是“算术”,而不是“逻辑”。

想要使用布尔数组作为0/1掩码(或“特征函数”)的人被迫使用某种渐开线表达式,例如(0-bools)(-1)*bools,并且很容易招致如果他忘了这件事就会陷入错误。

为什么会如此,以及获得所需行为的最佳方式是什么? (当然评论旁边)

2 个答案:

答案 0 :(得分:2)

关于运营商订单和数据类型。

>>> -B
array([ True, False], dtype=bool)

使用numpy时,布尔数组被视为布尔数组。应用于它们的每个操作,将首先尝试维护数据类型。那是方式:

>>> ~B
array([ True, False], dtype=bool)

-B
等价的

返回其元素的元素否定。但请注意,使用>>> B + 1 array([1, 2]) 会抛出警告,因为该函数已弃用。

当您使用以下内容时:

B

1boolean首先在引擎盖下转换为相同的数据类型。在数据类型促销中,numeric数组始终会转换为B数组。在上述情况下,int会投放到>>> B.astype(int) + 1 array([1, 2]) ,类似于:

>>> -B * 2
array([2, 0])

在你的例子中:

B

首先,数组-被运算符>>> -(B * 2) array([ 0, -2]) 否定,然后乘以2.可以通过显式数据转换或添加括号来采用所需的行为,以确保正确的操作顺序:

>>> -B.astype(int) * 2
array([ 0, -2])

B.astype(int)

请注意,B.view(np.int8)可以在没有characters的数据副本的情况下被替换,因为布尔值由.view表示,因此有8位,数据可以被视为整数{ {1}}方法,无需转换。

>>> B.view(np.int8)
array([0, 1], dtype=int8)

因此,简而言之,B.view(np.int8)B.astype(yourtype)将始终确保B[0,1]数字数组。

答案 1 :(得分:0)

Numpy数组是同源的 - 所有元素对于给定数组都具有相同的类型,并且数组对象存储的是什么类型。当您使用TrueFalse创建数组时,它是一个类型为bool的数组,运算符就会在数组上运行。因此,在对正常bool进行逻辑否定的情况下,您会发生逻辑否定,这并不奇怪。当您使用数组进行整数数学运算时,它们将转换为1和0。在你的所有例子中,那些是更多的异常情况,也就是说,它的行为不应该依赖于良好的代码。

正如评论中所建议的那样,如果你想用0和1的数组做数学运算,最好只做一个0和1的数组。但是,根据您对它们的要求,您可能会更好地查看numpy.where()等函数。

相关问题