前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >6-比较掩码布尔

6-比较掩码布尔

作者头像
用户1418372
发布2020-03-19 20:38:02
1.4K0
发布2020-03-19 20:38:02
举报
文章被收录于专栏:清晨我上码清晨我上码

比较 布尔逻辑

本节介绍了使用布尔掩码来检查和操作NumPy数组中的值。 当您要基于某些条件提取,修改,计数或以其他方式操纵数组中的值时,就会出现屏蔽:例如,您可能希望对大于某个值的所有值进行计数,或者可能删除高于某个值的所有异常值阈。在NumPy中,布尔掩码通常是完成这些类型任务的最有效方法。

计算下雨天的例子

在这里,我们将使用Pandas加载2014年西雅图市的每日降雨量统计信息(每天的降水量)

代码语言:javascript
复制
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import numpy as np
import pandas as pd
# 使用 pandas 提取 下雨的英尺数作为numpu数组
rainfall = pd.read_csv('../data/Seattle2014.csv')['PRCP'].values
inches = rainfall / 254.0  # 1/10mm -> inches
inches.shape
## 根据数组作图
import matplotlib.pyplot as plt
#Seaborn其实是在matplotlib的基础上进行了更高级的API封装
import seaborn; 
seaborn.set(color_codes=True)#设定颜色
# seaborn.distplot(x, bins=20, kde=False, rug=True);#设置了20个矩形条
plt.hist(inches, 40);
plt.show();

[图片上传失败...(image-ced9c0-1584522338880)]

该直方图使我们对数据的外观有了大致的了解:西雅图的绝大多数日子在2014年的实测降雨量几乎为零。但这并不能很好地传达我们想要的信息看:例如,一年中有多少雨天?那些雨天的平均降雨量是多少?有多少天降雨超过半英寸?

挖掘详细数据

一种解决方法是手动解决这些问题:遍历数据,每当我们看到某个所需范围内的值时就增加一个计数器。出于本章所讨论的原因,从时间和计算结果的角度来看,这种方法都效率很低。我们在NumPy数组计算中看到:通用函数,可以使用NumPy的ufuncs代替循环来对数组进行快速的逐元素算术运算。以相同的方式,我们可以使用其他ufunc在数组上进行逐元素比较,然后我们可以操纵结果来回答所遇到的问题。我们现在将数据放在一边,并讨论NumPy中的一些常规工具,以使用masking快速回答这种类型的问题。

比较运算符为ufuncs

numpy数组通用计算中,我们引入了ufuncs,尤其着重于算术运算符。我们看到在数组上使用+,-,*,/和其他会导致按元素进行操作。 NumPy还实现了比较运算符,例如<(小于)和>(大于)作为元素方式的ufunc。这些比较运算符的结果始终是具有布尔数据类型的数组。所有六个标准比较操作均可用:

代码语言:javascript
复制
# 与数组每个比较,也可以使用!= > ==等等
In [5]: 5<np.array([2,6,3])
Out[5]: array([False,  True, False])
# 也可以两个数组执行类似操作
In [7]: b=np.array([1,1,2])
In [8]: a=np.arange(3)
In [9]: a==b
Out[9]: array([False,  True,  True])

与算术运算符一样,比较运算符在NumPy中实现为ufunc;当使用x < 3其实调用内部NumPy使用np.less(x,3)。比较运算符及其等效ufunc如下所示:

代码语言:javascript
复制
==  np.equal        !=  np.not_equal
<   np.less         <=  np.less_equal
>   np.greater      >=  np.greater_equal

二维数组

代码语言:javascript
复制
In [27]: rng = np.random.randint(10,size=(3,3))
In [28]: rng
Out[28]: 
array([[1, 3, 3],
       [8, 7, 2],
       [7, 0, 9]])
In [29]: x>6
Out[29]: 
array([[False, False, False, False],
       [ True,  True, False, False],
       [False, False,  True, False]])
使用布尔数组

通过数组布尔运算可以统计很多对我们有用的信息

代码语言:javascript
复制
In [30]: x  = np.random.randint(10,size=(3,3))
In [31]: x
Out[31]: 
array([[1, 6, 0],
       [3, 3, 8],
       [0, 9, 7]])
#  计算数组小于等于3的数量,也可以使用np.sum(x<=3)
In [33]: np.count_nonzero(x<=3)
Out[33]: 5

用sum汇总的一个好处是可以根据行或者列来汇总

代码语言:javascript
复制
# 根据列汇总
In [45]: np.sum(x<=3,axis=0)
Out[45]: array([3, 1, 1])

np.any 和 np.all 方法用来判断数组任意一个元素是否符合条件和所有元素是否符合

代码语言:javascript
复制
In [49]: np.any(x<3)
Out[49]: True

In [50]: np.all(x<3)
Out[50]: False
###
In [53]: x
Out[53]: 
array([[1, 6, 0],
       [3, 3, 8],
       [0, 9, 7]])
In [51]: # 判断每行都是否都大于等于3。可以看到第二行满足
   ...: np.all(x >= 3, axis=1)
Out[55]: array([False,  True, False])
  • 最后 需要注意的是:如聚合:最小,最大和介于两者之间的内容所述,Python内置了sum(),any()和all()函数。它们的语法与NumPy版本的语法不同,特别是在多维数组上使用时,将失败或产生意外结果。对于这些示例,请确保使用np.sum(),np.any()和np.all()!
布尔运算符

我们已经看到了如何计算,例如,降雨少于四英寸的所有日子,或降雨大于两英寸的所有日子。但是,如果我们想知道降雨小于四英寸且大于一英寸的全天,该怎么办?这是通过Python的按位逻辑运算符&,|,^和〜完成的。与标准算术运算符一样,NumPy将这些重载为ufunc,它们在(通常为Boolean)数组中逐个元素地工作。

代码语言:javascript
复制
In [58]: import numpy as np
    ...: import pandas as pd
    ...: # use pandas to extract rainfall inches as a NumPy array
    ...: rainfall = pd.read_csv('data/Seattle2014.csv')['PRCP'].values
    ...: inches = rainfall / 254.0  # 1/10mm -> inches
    ...: inches.shape
Out[58]: (365,)
# 计算降雨量在0.5到1的天数
In [61]: 
    ...: np.sum((inches > 0.5) & (inches < 1))
Out[61]: 29

运算符等效ufunc运算符等效ufunc

代码语言:javascript
复制
&   np.bitwise_and      |   np.bitwise_or
^   np.bitwise_xor      ~   np.bitwise_not

通过这些条件就可以计算我们需要的信息

代码语言:javascript
复制
In [64]: 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.2 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.2 inches  : 75
布尔数组作为掩码参与数组运算

在上面,我们研究了直接在布尔数组上计算的聚合。一种更强大的模式是使用布尔数组作为掩码,以选择数据本身的特定子集。从前面返回x数组,假设我们想要一个数组,该数组的所有值都小于5,例如:

代码语言:javascript
复制
In [65]: x
Out[65]: 
array([[1, 6, 0],
       [3, 3, 8],
       [0, 9, 7]])
#可以很容易地为此条件获得一个布尔数组:
In [69]: test=x<3
In [70]: test
Out[70]: 
array([[ True, False,  True],
       [False, False, False],
       [ True, False, False]])

现在要从数组中选择这些值,我们只需在此布尔数组上建立索引即可;这称为屏蔽操作:

代码语言:javascript
复制
#根据test的索引对应x数组选择True的值
In [71]: x[test]
Out[71]: array([1, 0, 0])

应用到上面统计下雨天的例子中

代码语言:javascript
复制
# construct a mask of all rainy days
rainy = (inches > 0)

# construct a mask of all summer days (June 21st is the 172nd day)
days = np.arange(365)
summer = (days > 172) & (days < 262)

print("雨天的中位数:   ",
      np.median(inches[rainy]))
print("夏天雨天的中位数:  ",
      np.median(inches[summer]))
print("夏季雨天最大降水量: ",
      np.max(inches[summer]))
print("非夏天雨天的中位数:",
      np.median(inches[rainy & ~summer]))

通过组合布尔运算,屏蔽运算和聚合,我们可以非常快速地为我们的数据集回答这类问题。

易混淆

当使用&和|在整数上,表达式对元素的位进行运算。当使用and或or时,等效于要求Python将对象视为单个布尔实体。在Python中,所有非零整数都将评估为True。

代码语言:javascript
复制
In [75]: 
    ...: bool(42), bool(0)
Out[75]: (True, False)

In [76]: bool(42 or 0)
Out[76]: True
# 位运算
In [77]: bin(42 & 59)
Out[77]: '0b101010'
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 比较 布尔逻辑
    • 计算下雨天的例子
    • 挖掘详细数据
      • 比较运算符为ufuncs
        • 使用布尔数组
          • 布尔运算符
            • 布尔数组作为掩码参与数组运算
              • 易混淆
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档