2.2.4.2 masked_array缺失数据
Masked arrays是有缺失或无效条目的数组。
例如,假如我们有一个第四个条目无效的数组:
In [16]:
x = np.array([1, 2, 3, -99, 5])
描述这个数组的一个方式是创建masked array:
In [17]:
mx = np.ma.masked_array(x, mask=[0, 0, 0, 1, 0])
mx
Out[17]:
masked_array(data = [1 2 3 -- 5],
mask = [False False False True False],
fill_value = 999999)
Masked平均数会忽略masked数据:
In [18]:
mx.mean()
Out[18]:
2.75
In [19]:
np.mean(mx)
Out[19]:
2.75
警告:不是所有的Numpy函数都接收mask,例如,np.dot
,因此,请检查返回的类型。
masked_array
返回原始数组的一个视图:
In [20]:
mx[1] = 9
x
Out[20]:
array([ 1, 9, 3, -99, 5])
2.2.4.2.1 mask
你可以通过赋值来修改mask:
In [21]:
mx[1] = np.ma.masked
mx
Out[21]:
masked_array(data = [1 -- 3 -- 5],
mask = [False True False True False],
fill_value = 999999)
通过赋值可以清除mask:
In [22]:
mx[1] = 9
mx
Out[22]:
masked_array(data = [1 9 3 -- 5],
mask = [False False False True False],
fill_value = 999999)
mask也可以直接访问:
In [23]:
mx.mask
Out[23]:
array([False, False, False, True, False], dtype=bool)
masked条目可以通过填入一个给定值来变回一般的数组:
In [24]:
x2 = mx.filled(-1)
x2
Out[24]:
array([ 1, 9, 3, -1, 5])
mask也可以被清除:
In [25]:
mx.mask = np.ma.nomask
mx
Out[25]:
masked_array(data = [1 9 3 -99 5],
mask = [False False False False False],
fill_value = 999999)
2.2.4.2.2 领域相关的函数
masked数组包也包含一些领域相关的函数:
In [26]:
np.ma.log(np.array([1, 2, -1, -2, 3, -5]))
Out[26]:
masked_array(data = [0.0 0.6931471805599453 -- -- 1.0986122886681098 --],
mask = [False False True True False True],
fill_value = 1e+20)
笔记:对于高效无缝处理数组中的缺失值的支持将在Numpy 1.7中出现。现在还在优化中!
例子:Masked统计
加拿大的护林员在计算1903-1918年野兔和猞猁的数量时有些心烦意乱,数字经常出错。(尽管胡萝卜农场主不断的警告。)计算随着时间推移的平均数,忽略无效数据。
In [4]:
data = np.loadtxt('data/populations.txt')
populations = np.ma.masked_array(data[:,1:])
year = data[:, 0]
bad_years = (((year >= 1903) & (year <= 1910))
| ((year >= 1917) & (year <= 1918)))
# '&' means 'and' and '|' means 'or'
populations[bad_years, 0] = np.ma.masked
populations[bad_years, 1] = np.ma.masked
populations.mean(axis=0)
Out[4]:
masked_array(data = [40472.72727272727 18627.272727272728 42400.0],
mask = [False False False],
fill_value = 1e+20)
In [5]:
populations.std(axis=0)
Out[5]:
masked_array(data = [21087.656489006717 15625.799814240254 3322.5062255844787],
mask = [False False False],
fill_value = 1e+20)
注意,Matplotlib了解masked数组:
In [8]:
plt.plot(year, populations, 'o-')
Out[8]:
[<matplotlib.lines.Line2D at 0x10565f250>,
<matplotlib.lines.Line2D at 0x10565f490>,
<matplotlib.lines.Line2D at 0x10565f650>]