All men are sculptors, constantly chipping away the unwanted parts of their lives, trying to create their idea of a masterpiece —— Eddie Murphy
所有的人都是雕塑家,不断地消除生活中不必要的部分,试图建立自己的杰作理念 —— 埃迪·墨菲(Eddie Murphy)
import numpy as nparr = np.array([1, 2, 3, 4, 5, 6, 7, 8])
假设要对以上NumPy数组,需要计算小于4和大于6的元素之和。常规方法是采用for循环。
total = 0
for num in arr:
if (num<4) or (num>6):
total += num
print(total)
>>> 21
使用Mask可以完成相同的功能。首先从手动创建掩模开始:
"""这里True表示满足条件的元素"""
mask = [True, True, True, False, False, False, True, True]
arr[mask].sum()
>>> 21
查看掩码:
arr[mask]
>>> masked_array(data=[1, 2, 3, --, --, --, 7, 8],
mask=[False, False, False, True, True, True, False, False],
fill_value=999999)
Numpy提供了一个名为ma 的内置MaskedArray模块 。 该模块的masked_array()函数可以直接创建一个“ masked array”,在其中将不满足条件的元素呈现/标记为“ invalid” 。
注意 :现在,当mask=False或mask=0 ,字面意思是不要将此值标记为无效。 简而言之,在计算时将其包括在内 。 同样, mask=True或mask=1表示将此值标记为无效。
import numpy.ma as ma
"""First create a normal Numpy array"""
arr = np.array([1, 2, 3, 4, 5, 6, 7, 8])
ma_arr = ma.masked_array(arr, mask=[False, False, False, True, True, True, False, False])
ma_arr
>>>masked_array(data=[1, 2, 3, --, --, --, 7, 8],
mask=[False, False, False, True, True, True, False, False],
fill_value=999999)
也可以使用列表推导来创建掩码。 但是,由于要交换True和False值,因此可以使用波浪号~来反转布尔值。
arry = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9])
ma_arry = ma.masked_array(arry, mask=[~((a<4) or (a>6)) for a in arry])
ma_arry
>>>masked_array(data=[1, 2, 3, --, --, --, 7, 8, 9],
mask=[False, False, False, True, True, True, False, False,
False],
fill_value=999999)
根据屏蔽条件的类型,NumPy提供了其他几种内置屏蔽:
使用函数masked_less()过滤小于4的数字:
arr = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9])
ma_arr = ma.masked_less(arr, 4)
ma_arr.sum()
>>>39
要过滤小于等于数字的值,请使用masked_less_equal() 。
使用函数masked_less()过滤大于4的数字:
arr = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9])
ma_arr = ma.masked_greater(arr, 4)
ma_arr.sum()
>>>10
要过滤大于等于数字的值,请使用masked_greater_equal() 。
函数masked_inside()将过滤两个给定数字(包括两个数字)之间的值。 以下4到6之间的过滤器值。
arr = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9])
ma_arr = ma.masked_inside(arr, 4, 6)
ma_arr
>>>masked_array(data=[1, 2, 3, --, --, --, 7, 8, 9],
mask=[False, False, False, True, True, True, False, False,
False],
fill_value=999999)
函数masked_inside()将过滤两个给定数字(包括两个数字)之间的值。 以下4-6之外的过滤器值。
arr = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9])
ma_arr = ma.masked_outside(arr, 4, 6)
ma_arr
>>>masked_array(data=[--, --, --, 4, 5, 6, --, --, --],
mask=[ True, True, True, False, False, False, True, True,
True],
fill_value=999999)
实际的数据集通常具有许多缺失值(NaN)或一些奇怪的无穷大值(inf)。 这样的值在计算中产生问题,因此被忽略或推算。
任何值与nan运算,得到的结果都是nan,例如:
a = np.nan
print(a+1)
>>>nan
a = np.nan
b = np.inf
print(a+b)
>>>nan
可以使用masked_invalid()轻松排除NaN和无限值,该值将从计算中排除这些值。 这些无效值现在将表示为-- 。 此功能对于处理数据科学问题中大型数据集中的丢失数据非常有用 。
arr = np.array([1, 2, 3, np.nan, 5, 6, np.inf, 8, 9])
ma_arr = ma.masked_invalid(arr)
ma_arr
>>>masked_array(data=[1.0, 2.0, 3.0, --, 5.0, 6.0, --, 8.0, 9.0],
mask=[False, False, False, True, False, False, True, False,
False],
fill_value=1e+20)
arr.sum()
>>>nan
ma_arr.sum()
>>>34.0
本文参考自binary masks_Python中的Masks概念