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

相關文章
相關標籤/搜索