NumPy入门基础语法学习9

操作布尔数组

给定一个布尔数组,你可以实现很多有用的操作。首先打印出此前生成
的二维数组 x

 

print(x)

[[5 0 3 3]
 [7 9 3 5]
 [2 4 7 6]]
01. 统计记录的个数
如果需要统计布尔数组中 True 记录的个数,可以使用
np.count_nonzero 函数:
 
我们看到有 8 个数组记录是小于 6 的。另外一种实现方式是利用
np.sum 。在这个例子中, False 会被解释成 0 True 会被解释成
1
 
np.sum(x < 6)

8
sum() 的好处是,和其他 NumPy 聚合函数一样,这个求和也可以
沿着行或列进行:
 
 
# 每行有多少值小于6?
np.sum(x < 6, axis=1)

array([4, 2, 2])
这是矩阵中每一行小于 6 的个数。如要快速检查任意或者所有这些值是否为 True ,可以用(你一定
猜到了)
# 有没有值大于8?
 np.any(x > 8)

True
 # 有没有值小于0?
 np.any(x < 0)

 False
 # 是否所有值都小于10?
 np.all(x < 10)

 True
# 是否所有值都等于6? 
np.all(x == 6) 

 False
np.all() n p.any() 也可以用于沿着特定的坐标轴,例如:
# 是否每行的所有值都小于8?
 np.all(x < 8, axis=1)
 
 array([ True, False, True], dtype=bool)
这里第 1 行和第 3 行的所有元素都小于 8 ,而第 2 行不是所有元素都小于 8 。最后需要提醒的是,
Python 有内置的 sum() any() all() 函数,这些函数在 NumPy 中有不同的语
法版本。如果在多维数组上混用这两个版本,会导致失败或产生不
可预知的错误结果。因此,确保在以上的示例中用的都是
np.sum() np.any() np.all() 函数。
 

02. 布尔运算符

这可以通过 Python 的逐位逻辑运算符( bitwise logic operator & | ^ ~ 来实现。同标准的算术运算符一样,
NumPy 用通用函数重载了这些逻辑运算符,这样可以实现数组的 逐位运算(通常是布尔运算)。
例如,可以写如下的复合表达式:
 np.sum((inches > 0.5) & (inches < 1)) 

 29
可以看到,降水量在 0.5 英寸 ~1 英寸间的天数是 29 天。
请注意,这些括号是非常重要的,因为有运算优先级规则。如果去
掉这些括号,该表达式会变成以下形式,这会导致运行错误:
 
利用 A AND B NOT (A OR B) 的等价原理(你应该在基础逻辑
课程中学习过),可以用另外一种形式实现同样的结果:
 
将比较运算符和布尔运算符合并起来用在数组上,可以实现更多有
效的逻辑运算操作。以下表格总结了逐位的布尔运算符和其对应的通用函数。
 
利用这些工具,就可以回答那些关于天气数据的问题了。以下的示
例是结合使用掩码和聚合实现的结果计算:
 print("Number days without rain: ", np.sum(inches == 0))
 print("Number days with rain: ", np.sum(inches != 0)) 
 print("Days with more than 0.5 inches:", np.sum(inches > 0.5)) 
 print("Rainy days with < 0.1 inches :", np.sum((inches > 0) & (inches < 0.2)

 Number days without rain: 215
 Number days with rain: 150
 Days with more than 0.5 inches: 37 
 Rainy days with < 0.1 inches : 75

2.6.4 将布尔数组作为掩码

在前面的小节中,我们看到了如何直接对布尔数组进行聚合计算。一种
更强大的模式是使用布尔数组作为掩码,通过该掩码选择数据的子数据
集。以前面小节用过的 x 数组为例,假设我们希望抽取出数组中所有小
5 的元素:
 
 
如前面介绍过的方法,利用比较运算符可以得到一个布尔数组:
 
 x < 5 

 array([[False, True, True, True],
        [False, False, True, False], 
        [ True, True, False, False]], dtype=bool)

现在为了将这些值从数组中选出,可以进行简单的索引,即掩码操作:

x[x < 5] 

array([0, 3, 3, 3, 2, 4])
现在返回的是一个一维数组,它包含了所有满足条件的值。换句话说,
所有的这些值是掩码数组对应位置为 True 的值。现在,可以对这些值做任意操作,例如可以根据西雅图降水数据进行一
些相关统计:
 # 为所有下雨天创建一个掩码
 rainy = (inches > 0) 
 # 构建一个包含整个夏季日期的掩码(6月21日是第172天)
 summer = (np.arange(365) - 172 < 90) & (np.arange(365) - 172 > 0)

print("Median precip on rainy days in 2014 (inches): ", np.median(inches[rainy]))

print("Median precip on summer days in 2014 (inches): ", np.median(inches[summer])) 

print("Maximum precip on summer days in 2014 (inches): ", np.max(inches[summer]))

print("Median precip on non-summer rainy days (inches):", np.median(inches[rainy & ~summer])) 

 Median precip on rainy days in 2014 (inches): 0.194881889764
 Median precip on summer days in 2014 (inches): 0.0 
 Maximum precip on summer days in  2014 (inches): 0.850393700787 
 Median precip on non-summer rainy days (inches): 0.200787401575
通过将布尔操作、掩码操作和聚合结合,可以快速回答对数据集提出的
这类问题。使用关键字 and / or 与使用逻辑操作运算符 & / | 人们经常困惑于关键字 and or ,以及逻辑操作运算符 & |
区别是什么,什么时候该选择哪一种?
 
它们的区别是: and or 判断整个对象是真或假,而 & | 是指
每个对象中的比特位。当你使用 and or 时,就等于让 Python 将这个对象当作整个布尔
实体。在 Python 中,所有非零的整数都会被当作是 True
 
当你对整数使用 & | 时,表达式操作的是元素的比特,将 and
or 应用于组成该数字的每个比特:
 
 
请注意, & | 运算时,对应的二进制比特位进行比较以得到最终结果。
当你在 NumPy 中有一个布尔数组时,该数组可以被当作是由比特
 
字符组成的,其中 1 = True 0 = False 。这样的数组可以用上
面介绍的方式进行 & | 的操作:
 
A = np.array([1, 0, 1, 0, 1, 0], dtype=bool) 
B = np.array([1, 1, 1, 0, 1, 1], dtype=bool)
A | B

array([ True,  True,  True, False,  True,  True])
而用 or 来计算这两个数组时, Python 会计算整个数组对象的真或
假,这会导致程序出错:
 
 
同样,对给定
数组进行逻辑运算时,你也应该使用 | & ,而不是
or and
 
 
如果试图计算整个数组的真或假,程序也同样会给出 ValueError
的错误:
因此可以记住: and or 对整个对象执行单个布尔运算,而 &
| 对一个对象的内容(单个比特或字节)执行多个布尔运算。对于
NumPy 布尔数组,后者是常用的操作。
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值