所谓掩膜数组是指数据和掩膜共同构成的数组。这里的数据通常是指不完整或包含缺省值的数据。对于完整的数据来说也不需要转换为掩膜数组。掩膜是指用来将数据中不完整或包含缺省值的的地方给遮住。被遮住的部分就不再参与后续运算。
在大多数情况下,数据是不完整或存在无效值的情况。因此,numpy提供了numpy.ma模块解决这一问题。numpy.ma 模块所产生的掩膜包含两种:
False 表示对应的值是有效值,不进行遮盖
True 表示对应的值是无效值,进行遮盖
numpy.ma 模块最主要的就是 MaskedArray 类,它是 numpy.ndarray 的子类。
创建掩膜数组
numpy,ma模块中提供了多种方法用以创建掩膜数组,主要都是基于 MaskedArray 类。
首先导入库并创建演示数组:
import numpy as np
import numpy.ma as ma
x = (np.random.random((3,4))*100 + 15).round()
array([[ 69., 40., 51., 79.],
[ 34., 57., 97., 98.],
[ 23., 74., 24., 52.]])
ma.MaskedArray(data = x, mask = np.logical_and(x < 50, x > 20))
masked_array(data =
[[69.0 -- 51.0 79.0]
[-- 57.0 97.0 98.0]
[-- 74.0 -- 52.0]],
mask =
[[False True False False]
[ True False False False]
[ True False True False]],
fill_value = 1e+20)
直接使用MaskedArray类创建掩膜数组时,直接提供原始数组及掩膜即可。
注意:
掩膜的维度大小和原始数组的维度大小要一致。 默认情况下 copy 参数的值为 False,表示只进行浅拷贝,即拷贝原对象的引用。就是说如果更改了复制对象的数据的话,原始数组(被复制对象)的数据也会发生相同的变化。 不明确指定数据类型时,默认数据类型为 numpy.float64
用此方式创建掩膜数组和直接用 MaskedArray 创建相同。
ma.masked_array(x, mask = np.logical_and(x < 50, x > 20))
masked_array(data =
[[69.0 -- 51.0 79.0]
[-- 57.0 97.0 98.0]
[-- 74.0 -- 52.0]],
mask =
[[False True False False]
[ True False False False]
[ True False True False]],
fill_value = 1e+20)
注意事项同上。
比如,numpy.ma模块中的条件判断函数:
# 对大于 80 的数进行掩膜处理
ma.masked_greater(x, 80)
masked_array(data =
[[-999.0 40.0 51.0 79.0]
[34.0 57.0 -- --]
[23.0 74.0 24.0 52.0]],
mask =
[[False False False False]
[False False True True]
[False False False False]],
fill_value = 1e+20)
# 对小于等于 0 的数进行掩膜处理
ma.masked_less_equal(x, 0)
masked_array(data =
[[-- 40.0 51.0 79.0]
[34.0 57.0 97.0 98.0]
[23.0 74.0 24.0 52.0]],
mask =
[[ True False False False]
[False False False False]
[False False False False]],
fill_value = 1e+20)
# 对大于等于30小于等于70的数进行掩膜处理
ma.masked_inside(x, 30, 70)
masked_array(data =
[[-999.0 -- -- 79.0]
[-- -- 97.0 98.0]
[23.0 74.0 24.0 --]],
mask =
[[False True True False]
[ True True False False]
[False False False True]],
fill_value = 1e+20)
# 对小于20和大于80的数进行掩膜处理
ma.masked_outside(x, 20, 80)
masked_array(data =
[[-- 40.0 51.0 79.0]
[34.0 57.0 -- --]
[23.0 74.0 24.0 52.0]],
mask =
[[ True False False False]
[False False True True]
[False False False False]],
fill_value = 1e+20)
# 掩膜版的where函数
# 不同数组条件的掩膜处理
ma.masked_where(y > 90, x)
masked_array(data =
[[-999.0 -- 51.0 79.0]
[-- 57.0 -- --]
[-- 74.0 -- 52.0]],
mask =
[[False True False False]
[ True False True True]
[ True False True False]],
fill_value = 1e+20)
ma.masked_where(x < 0, x)
masked_array(data =
[[-- 40.0 51.0 79.0]
[34.0 57.0 97.0 98.0]
[23.0 74.0 24.0 52.0]],
mask =
[[ True False False False]
[False False False False]
[False False False False]],
fill_value = 1e+20)
除了示例列出的函数之外还有其它函数可以用于创建掩膜数组。在选择掩膜函数创建掩膜数组时,确保知道要做什么。
获取数据及掩膜
在上述的示例中可以看到掩膜数组包含三个属性: data,mask,fill_value。
获取数据
.data 属性包含的是原始数组的数据,而不是掩膜后的数据。除了使用 .data 属性获取数组的数据之外,还可以通过 __array__ 方法获取数据,也可以通过 getdata 函数获取数组数据。
y.data
array([[-999., 40., 51., 79.],
[ 34., 57., 97., 98.],
[ 23., 74., 24., 52.]])
y.__array__()
array([[-999., 40., 51., 79.],
[ 34., 57., 97., 98.],
[ 23., 74., 24., 52.]])
ma.getdata(y)
array([[-999., 40., 51., 79.],
[ 34., 57., 97., 98.],
[ 23., 74., 24., 52.]])
获取掩膜
获取掩膜的方式与获取数据的方式大同小异。除了 .mask 属性之外,还可以通过 getmask 和 getmaskarray 函数获取掩膜。如果数组不是掩膜数组的话,使用 getmask 函数时会返回 False,而 getmaskarray 会返回和数组相同大小的False数组。
获取有效数据
y[~y.mask] 或 y[np.logical_not(y.mask)]
masked_array(data = [-999.0 51.0 79.0 57.0 97.0 98.0 74.0 52.0],
mask = [False False False False False False False False],
fill_value = 1e+20)
指定掩膜和去掩膜
在创建掩膜数组时,如果需要对指定索引的数据进行掩膜,可以不需要利用条件掩膜函数,而通过 numpy.ma 模块中的 masked 常数进行掩膜操作。
y[0,0] = ma.masked
masked_array(data =
[[-- -- 51.0 79.0]
[-- 57.0 97.0 98.0]
[-- 74.0 -- 52.0]],
mask =
[[ True True False False]
[ True False False False]
[ True False True False]],
fill_value = 1e+20)
不推荐直接更改 mask 属性的值实现上述操作。
去掩膜
在执行去掩膜操作时,可直接对需要去掩膜的数据进行赋值。
注意:
如果掩膜数组是硬掩模(hardmask)的话,直接赋值操作将会失败。在执行赋值操作之前需要将硬掩模转换为软掩膜。 .hardmask属性记录了是否为硬掩膜。
如果要对整个数组执行去掩膜操作的话,最简单的方式是将 numpy.ma.nomask 常数赋值给 .mask 参数。
y.mask = ma.nomask
masked_array(data =
[[-999.0 40.0 51.0 79.0]
[34.0 57.0 97.0 98.0]
[23.0 74.0 24.0 52.0]],
mask =
[[False False False False]
[False False False False]
[False False False False]],
fill_value = 1e+20)
一开始提到了MaskedArray 类是 numpy.ndarray 类的子类,所以掩膜数组也可以执行 ndarray 数组几乎所有的操作,比如算数运算,形状变换,索引切片等操作。
掩膜数组在执行计算过程中,会自动处理缺省值,除0,负值开方等情况。