[Python数据科学手册]2.6比较,掩码和布尔逻辑

563 阅读3分钟
# 这一节将会介绍如何用布尔掩码来查看和操作 NumPy 数组中的值。
# 当你想基于某些准则来抽取、修改、计数或对一个数组中的值进行其他操作时,掩码就可以派上用场了。

#示例:统计下雨天数
import numpy as np 
import pandas as pd 

#利用pandas抽取降雨量,放入一个Numpy数组
rainfall = pd.read_csv('D:\Seattle2014.csv')['PRCP'].values
inches = rainfall / 254 #1/10mm ->inches
inches.shape
# 这个数组包含 365 个值,
# 给出了从 2014 年 1 月 1 日至 2014 年 12 月 31 日每天的降水量。
# 这里降水量的单位是英寸。
#做一个快速的可视化,用Matplotlib生成下雨天数的直方图
# %matplotlib inline
import matplotlib.pyplot as plt 
import seaborn;seaborn.set() #设置绘图风格
plt.hist(inches,40);

# 6 种标准的比较操作:
x = np.array([1,2,3,4,5])
x < 3
x > 3
x <= 3
x >= 3
x != 3
x == 3
(2 * x) == (x ** 2)

# 比较运算通用函数也可以用于任意形 状、大小的数组
rng = np.random.RandomState(0)
x = rng.randint(10,size=(3,4))
x < 6

#操作布尔数组
#1统计记录的个数
#如果需要统计布尔数组中 True 记录的个数,可以使用 np.count_nonzero 函数:
np.count_nonzero(x < 6) #有多少值小于6
#另外一种实现方式是利用 np.sum。
# 在这个例子中,False 会被解释成 0,True 会被解释成 1:
np.sum(x < 6)
# sum() 的好处是和其他 NumPy 聚合函数一样,这个求和也可以 沿着行或列进行:
np.sum(x < 6,axis=1) #每行有多少值小于6?

# 如要快速检查任意或者所有这些值是否为 True,
# 可以用np.any() 或 np.all():
np.any(x > 8) #有没有值大于8
np.any(x < 0) #有没有值小于0
np.all(x < 10) #是否所有值都小于10
np.all( x == 6) #是否所有值都等于6
# np.all() 和n p.any() 也可以用于沿着特定的坐标轴:
np.all( x < 8, axis=1) #是否每行所有值都小于8

#布尔运算符
np.sum((inches > 0.5) & (inches < 1)) #降水量在 0.5 英寸~1 英寸间的天数
np.sum(~((inches <= 0.5) | (inches >= 1))) #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)))

#将布尔数组作为掩码
x
x<5
# 现在为了将这些值从数组中选出,可以进行简单的索引,即掩码操作:
x [x<5] #现在返回的是一个一维数组,它包含了所有满足条件的值

# 为所有下雨天创建一个掩码 
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]))

A = np.array([1,0,1,0,1,0],dtype=bool)
B = np.array([1,1,1,0,1,1],dtype=bool)
A | B
x = np.arange(10)
( x > 4 ) & (x < 8)
# and 和 or 对整个对象执行单个布尔运算,
# 而 & 和 | 对一个对象的内容(单个比特或字节)执行多个布尔运算。
# 对于 NumPy 布尔数组,后者是常用的操作。