2.2.4.2 masked_array缺失数据

Masked arrays是有缺失或无效条目的数组。

例如,假如我们有一个第四个条目无效的数组:

In [16]:

  1. x = np.array([1, 2, 3, -99, 5])

描述这个数组的一个方式是创建masked array:

In [17]:

  1. mx = np.ma.masked_array(x, mask=[0, 0, 0, 1, 0])
  2. mx

Out[17]:

  1. masked_array(data = [1 2 3 -- 5],
  2. mask = [False False False True False],
  3. fill_value = 999999)

Masked平均数会忽略masked数据:

In [18]:

  1. mx.mean()

Out[18]:

  1. 2.75

In [19]:

  1. np.mean(mx)

Out[19]:

  1. 2.75

警告:不是所有的Numpy函数都接收mask,例如,np.dot,因此,请检查返回的类型。

masked_array返回原始数组的一个视图:

In [20]:

  1. mx[1] = 9
  2. x

Out[20]:

  1. array([ 1, 9, 3, -99, 5])

2.2.4.2.1 mask

你可以通过赋值来修改mask:

In [21]:

  1. mx[1] = np.ma.masked
  2. mx

Out[21]:

  1. masked_array(data = [1 -- 3 -- 5],
  2. mask = [False True False True False],
  3. fill_value = 999999)

通过赋值可以清除mask:

In [22]:

  1. mx[1] = 9
  2. mx

Out[22]:

  1. masked_array(data = [1 9 3 -- 5],
  2. mask = [False False False True False],
  3. fill_value = 999999)

mask也可以直接访问:

In [23]:

  1. mx.mask

Out[23]:

  1. array([False, False, False, True, False], dtype=bool)

masked条目可以通过填入一个给定值来变回一般的数组:

In [24]:

  1. x2 = mx.filled(-1)
  2. x2

Out[24]:

  1. array([ 1, 9, 3, -1, 5])

mask也可以被清除:

In [25]:

  1. mx.mask = np.ma.nomask
  2. mx

Out[25]:

  1. masked_array(data = [1 9 3 -99 5],
  2. mask = [False False False False False],
  3. fill_value = 999999)

2.2.4.2.2 领域相关的函数

masked数组包也包含一些领域相关的函数:

In [26]:

  1. np.ma.log(np.array([1, 2, -1, -2, 3, -5]))

Out[26]:

  1. masked_array(data = [0.0 0.6931471805599453 -- -- 1.0986122886681098 --],
  2. mask = [False False True True False True],
  3. fill_value = 1e+20)

笔记:对于高效无缝处理数组中的缺失值的支持将在Numpy 1.7中出现。现在还在优化中!

例子:Masked统计

加拿大的护林员在计算1903-1918年野兔和猞猁的数量时有些心烦意乱,数字经常出错。(尽管胡萝卜农场主不断的警告。)计算随着时间推移的平均数,忽略无效数据。

In [4]:

  1. data = np.loadtxt('data/populations.txt')
  2. populations = np.ma.masked_array(data[:,1:])
  3. year = data[:, 0]
  4. bad_years = (((year >= 1903) & (year <= 1910))
  5. | ((year >= 1917) & (year <= 1918)))
  6. # '&' means 'and' and '|' means 'or'
  7. populations[bad_years, 0] = np.ma.masked
  8. populations[bad_years, 1] = np.ma.masked
  9. populations.mean(axis=0)

Out[4]:

  1. masked_array(data = [40472.72727272727 18627.272727272728 42400.0],
  2. mask = [False False False],
  3. fill_value = 1e+20)

In [5]:

  1. populations.std(axis=0)

Out[5]:

  1. masked_array(data = [21087.656489006717 15625.799814240254 3322.5062255844787],
  2. mask = [False False False],
  3. fill_value = 1e+20)

注意,Matplotlib了解masked数组:

In [8]:

  1. plt.plot(year, populations, 'o-')

Out[8]:

  1. [<matplotlib.lines.Line2D at 0x10565f250>,
  2. <matplotlib.lines.Line2D at 0x10565f490>,
  3. <matplotlib.lines.Line2D at 0x10565f650>]

2.2.4.2 masked_array缺失数据 - 图1