6-比较掩码布尔

比较 布尔逻辑

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

计算下雨天的例子

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

#!/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。这些比较运算符的结果始终是具有布尔数据类型的数组。所有六个标准比较操作均可用:

# 与数组每个比较,也可以使用!= > ==等等
In [5]: 5

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

==  np.equal        !=  np.not_equal
<   np.less         <=  np.less_equal
>   np.greater      >=  np.greater_equal

二维数组

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]])

使用布尔数组

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

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汇总的一个好处是可以根据行或者列来汇总

# 根据列汇总
In [45]: np.sum(x<=3,axis=0)
Out[45]: array([3, 1, 1])

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

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)数组中逐个元素地工作。

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

&   np.bitwise_and      |   np.bitwise_or
^   np.bitwise_xor      ~   np.bitwise_not

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

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,例如:

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]])

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

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

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

# 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。

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'

更新github

你可能感兴趣的:(6-比较掩码布尔)