Numpy系列(十)- 掩码数组

简介

有时候数据集中存在缺失、异常或者无效的数值,咱们能够标记该元素为被屏蔽(无效)状态。python

import numpy as np
import numpy.ma as ma
x = np.array([1, 2, 3, -99, 5])
x
Out[289]: array([  1,   2,   3, -99,   5])

如今能够创造一个掩码数组(标记第四个元素为无效状态)。数组

mx = ma.masked_array(x, mask=[0, 0, 0, 1, 0])
mx
Out[291]: 
masked_array(data=[1, 2, 3, --, 5],
             mask=[False, False, False,  True, False],
       fill_value=999999)

接下来能够计算平均值而不用考虑无效数据。函数

mx.mean()
Out[292]: 2.75

 访问掩码

可经过其mask属性访问掩码数组的掩码。咱们必须记住,掩码中的True条目表示无效数据。spa

mx
Out[293]: 
masked_array(data=[1, 2, 3, --, 5],
             mask=[False, False, False,  True, False],
       fill_value=999999)
mx.mask
Out[294]: array([False, False, False,  True, False])

只访问有效数据

当只想访问有效数据时,咱们能够使用掩码的逆做为索引。能够使用numpy.logical_not函数或简单使用~运算符计算掩码的逆:code

x = ma.array([[1, 2], [3, 4]], mask=[[0, 1], [1, 0]])
x[~x.mask]
masked_array(data = [1 4],
             mask = [False False],
       fill_value = 999999)

另外一种检索有效数据的方法是使用compressed方法,该方法返回一维ndarray(或其子类之一,取决于baseclass属性):对象

x.compressed()
Out[297]: array([1, 4])

修改掩码

经过将True赋给掩码,能够当即屏蔽数组的全部数据:blog

x = ma.array([1, 2, 3], mask=[0, 0, 1])
x.mask = True
x
Out[300]: 
masked_array(data=[--, --, --],
             mask=[ True,  True,  True],
       fill_value=999999,
            dtype=int32)

最后,能够经过向掩码分配一系列布尔值来对特定数据条目进行掩码和/或取消掩码:继承

x = ma.array([1, 2, 3])
x.mask = [0, 1, 0]
x
Out[303]: 
masked_array(data=[1, --, 3],
             mask=[False,  True, False],
       fill_value=999999)

 取消掩码

要取消屏蔽一个或多个特定数据条目,咱们只需为它们分配一个或多个新的有效值:索引

x = ma.array([1, 2, 3], mask=[0, 0, 1])
x
Out[305]: 
masked_array(data=[1, 2, --],
             mask=[False, False,  True],
       fill_value=999999)
x[-1] = 5
x
Out[307]: 
masked_array(data=[1, 2, 5],
             mask=[False, False, False],
       fill_value=999999)

要取消屏蔽掩码数组的全部掩码条目(假设掩码不是硬掩码),最简单的解决方案是将常量nomask分配给掩码:class

x = ma.array([1, 2, 3], mask=[0, 0, 1])
x
Out[309]: 
masked_array(data=[1, 2, --],
             mask=[False, False,  True],
       fill_value=999999)
x.mask = ma.nomask
x
Out[311]: 
masked_array(data=[1, 2, 3],
             mask=[False, False, False],
       fill_value=999999)

 索引和切片

因为MaskedArraynumpy.ndarray的子类,它会继承其用于索引和切片的机制。

当访问没有命名字段的被掩蔽数组的单个条目时,输出是标量(若是掩码的相应条目是False)或特殊值masked (若是掩码的相应条目为True):

x = ma.array([1, 2, 3], mask=[0, 0, 1])
x
Out[313]: 
masked_array(data=[1, 2, --],
             mask=[False, False,  True],
       fill_value=999999)
x[0]
Out[314]: 1
x[-1]
Out[315]: masked
x[-1] is ma.masked
Out[316]: True

若是掩蔽的数组具备命名字段,访问单个条目将返回numpy.void对象(若是没有掩码),或者若是至少一个字段具备与初始数组相同的dtype的0d掩码数组的字段被屏蔽。

y = ma.masked_array([(1,2), (3, 4)],mask=[(0, 0), (0, 1)],dtype=[('a', int), ('b', int)])
y[0]
Out[318]: (1, 2)
y[-1]
Out[319]: (3, --)

当访问切片时,输出是掩蔽的数组,其data属性是原始数据的视图,而且其掩码是nomask(若是没有无效条目原始数组)或原始掩码的相应切片的副本。须要复制以免将掩模的任何修改传播到原始版本。

x = ma.array([1, 2, 3, 4, 5], mask=[0, 1, 0, 0, 1])
mx = x[:3]
mx
Out[322]: 
masked_array(data=[1, --, 3],
             mask=[False,  True, False],
       fill_value=999999)
mx[1] = -1
mx
Out[324]: 
masked_array(data=[1, -1, 3],
             mask=[False, False, False],
       fill_value=999999)
x.mask
Out[325]: array([False, False, False, False,  True])
x.data
Out[326]: array([ 1, -1,  3,  4,  5])

访问具备结构化数据类型的掩蔽数组的字段会返回MaskedArray

相关文章
相关标签/搜索