numpy.ma

numpy.ma模块

基本原理


当数组元素包括缺失值或异常值时,该数组被称为掩码数组。numpy.ma模块的工作方式可以这么来解释:支持数值数组中包含掩码元素。

什么是掩码数组呢?


在很多情况下,数据集可能是不完整或存在无效数据的。例如,一个传感器对于某个数值可能有以下两种存储情况:存储失败、存入一个无效数据。numpy.ma模块通过引入掩码数组,为这种问题的解决提供了一种便捷的方法。
掩码数组是将标准的多维数组numpy.ndarray和掩码相结合。掩码要么是nomask,表示与该掩码有关数组的所有值都是有效的。要么是一个布尔值数组,用于确定关联数组的每个元素值是否有效。当掩码中某个元素值为False,那么关联数组的对应元素是有效的,即被认为是未掩码的。当掩码中某个元素值为True,那么关联数组的对应元素是无效的,即被认为是掩码的。
这个包可以确保掩码项不参与计算。
为了让大家有一个直观的认识,我们给出下例:

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

我们想要将x数组中第四个值标记为无效数据。最便捷的方法是创建一个掩码数组:

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

现在,我们可以在不考虑-1这个异常值的情况下,计算数组x的均值:

print('仅仅计算[1, 2, 3, 5]的均值,计算结果为:{}'.format(mx.mean()))

仅仅计算[1, 2, 3, 5]的均值,计算结果为:2.75

numpy.ma模块

numpy.ma模块最主要的特性是掩码数组MaskedArray类,该类是多维数组numpy.ndarray的子类。掩码数组的属性以及方法详见MaskedArray class。
numpy.ma模块可以当作numpy包的补充:

import numpy as np
import numpy.ma as ma

我们可以这样子创建一个第二个元素无效的数组:

y = ma.array([1, 2, 3], mask = [0, 1, 0])

我们可以创建一个掩码数组,其中所有接近1.e20的值都是无效的:

z = ma.masked_values([1.0, 1.e20, 3.0, 4.0], 1.e20)

更多创建掩码数组的方法详见Constructing masked arrays。

使用numpy.ma

构建掩码数组


有如下几种方法来创建掩码数组。

  • 第一种方式是直接调用MaskedArray类。
  • 第二种方式是使用两种掩码数组构造函数,arraymasked_array
    • array(data[, dtype, copy, order, mask, …]): 定义了掩码值的数组类
    • masked_array: 和MaskedArray一样
  • 第三种方式是获取现有数组的视图。在这种情况下,如果数组没有命名字段,或者没有与数组结构相同的布尔数组,则将视图的掩码设置为nomask
x = np.array([1, 2, 3])
x.view(ma.MaskedArray)

masked_array(data=[1, 2, 3],
mask=False,
fill_value=999999)

x = np.array([(1, 1.), (2, 2.)], dtype=[('a',int), ('b', float)])
x.view(ma.MaskedArray)

masked_array(data=[(1, 1.0), (2, 2.0)],
mask=[(False, False), (False, False)],
fill_value=(999999, 1.e+20),
dtype=[(‘a’, ‘<i4’), (‘b’, ‘<f8’)])

  • 以下函数也可以创建掩码数组:
函数名 功能
asarray(a[, dtype, order]) 基于给定的数值类型将输入数据转换为掩码数组
asanyarray(a[, dtype]) 不改变子类的前提下,将输入数据转换为掩码数组
fix_invalid(a[, mask, copy, fill_value]) 将输入数组中的无效元素用填充值进行替代
masked_equal(x, value[, copy]) 对数组中等于value的值进行掩码操作
masked_greater(x, value[, copy]) 对数组中大于value的值进行掩码操作
masked_greater_equal(x, value[, copy]) 对数组中大于等于value的值进行掩码操作
masked_inside(x, v1, v2[, copy]) 对数组中落在给定区间的值进行掩码操作
masked_invalid(a[, copy]) 对数组中无效数据(例如NaN或inf)进行掩码操作
masked_less(x, value[, copy]) 对数组中小于value的值进行掩码操作
masked_less_equal(x, value[, copy]) 对数组中小于等于value的值进行掩码操作
masked_not_equal(x, value[, copy]) 对数组中不等于value的值进行掩码操作
masked_object(x, value[, copy, shrink]) 对数组(元素为’cats’等对象)中等于value的值进行掩码操作
masked_outside(x, v1, v2[, copy]) 对数组中落在给定区间之外的值进行掩码操作
masked_values(x, value[, rtol, atol, copy, …]) 被掩码部分替换为--
masked_where(condition, a[, copy]) 对数组中满足条件的部分进行掩码操作

访问数据


掩码数组的底层数据可以通过以下方式进行访问:

  • 通过data属性。输出是数组的视图,该数组的类型取决于掩码数组创建时的底层数据类型,可能为numpy.ndarray或其子类。
  • 通过__array__方法。输出为多维数组numpy.ndarray
  • 直接将掩码数组的视图视为多维数组numpy.ndarray或其子类之一(实际上是使用data属性来完成)。
  • 通过使用getdata函数。
    如果某些项被标已经被标记为无效,那么这些方法的结果都差强人意。有一个通用规则,如果需要一个没有任何掩码项的数组表示,建议使用填充filled的方法填充数组。

访问掩码


掩码数组可以通过其mask属性获取掩码。我们必须记住掩码中的True表示无效数据。使用getmaskgetmaskarray函数也可以获取到掩码。如果x为掩码数组getmask(x)将返回x的掩码,否则返回nomask。如果x为掩码数组getmaskarray(x)将返回x的掩码。如果x没有无效值或者其不为掩码数组,该函数返回len(x)False组成的布尔型数组。

仅获取有效值

为了检索数组中的有效值,我们可以使用掩码取反作为索引。掩码取反操作可以使用函数numpy.logical_not来完成,或者仅仅使用~操作符:

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()

array([1, 4])
备注:compressed的返回值通常为1维。

修改掩码


屏蔽一个条目


将一个掩码数组中的一个或多个特定项标记为无效的推荐方法是将掩码值masked赋给它们:

x = ma.array([1, 2, 3])
x[0] = ma.masked
x

masked_array(data=[–, 2, 3],
mask=[ True, False, False],
fill_value=999999)

y = ma.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
y[(0, 1, 2), (1, 2, 0)] = ma.masked
y

masked_array(
data=[[1, --, 3],
[4, 5, --],
[–, 8, 9]],
mask=[[False, True, False],
[False, False, True],
[ True, False, False]],
fill_value=999999)

z = ma.array([1, 2, 3, 4])
z[:-2] = ma.masked
z

masked_array(data=[–, --, 3, 4],
mask=[ True, True, False, False],
fill_value=999999)

另外一种方法就是使用mask直接修改掩码,但是这种方法已经被废除了。
注意:
当使用简单的,非结构化的数据类型创建新的掩码数组时,掩码会被初始化为nomask,相当于布尔值序列全为False
一个数组中的所有元素可以一并设置其掩码为True:

x = ma.array([1, 2, 3], mask=[0, 0, 1])
x.mask = True
x

masked_array(data=[–, --, --],
mask=[ True, True, True],
fill_value=999999,
dtype=int32)

可以通过对布尔值序列进行赋值来确定数组中的哪些元素用掩码表示:

x = ma.array([1, 2, 3])
x.mask = [0, 1, 0]
x

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

对屏蔽条目解除屏蔽

我们可以通过对屏蔽条目赋予新的有效值来解除其屏蔽:

x = ma.array([1, 2, 3], mask=[0, 0, 1])
x

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

x[-1] = 5
x

masked_array(data=[1, 2, 5],
mask=[False, False, False],
fill_value=999999)

注意:
当掩码数组属性为hard mask时,可能不能有效地对其解除屏蔽。这个特性是为了防止用户对掩码值进行覆盖。要想取消数组的hard_mask属性,必须在解除屏蔽前先对其利用soften_mask方法进行软化。当然,修改完毕之后也可以使用harden_mask属性防止掩码部分被修改:

x = ma.array([1, 2, 3], mask=[0, 0, 1], hard_mask=True)
x

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

x[-1] = 5
x

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

x.soften_mask()              # 软化
x[-1] = 5
x

masked_array(data=[1, 2, 5],
mask=[False, False, False],
fill_value=999999)

x[-1] = ma.masked
xx.harden_mask()             # 防止掩码部分修改
x[-1] = 2
x

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

对掩码数组(非hard mask)所有屏蔽部分解屏蔽的最简单方法是给mask赋常数nomask:

x = ma.array([1, 2, 3], mask=[0, 0, 1])
x

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

x.mask = ma.nomask
x

masked_array(data=[1, 2, 3],
mask=[False, False, False],
fill_value=999999)

索引和切片


由于掩码数组MaskedArray是多维数组numpy.ndarray的子类,所以它继承了索引和切片的机制。
当获取一个没有命名空间的掩码数组的单一元素时,输出值既不是标量(如果掩码的对应项为False)也不是特殊值masked(如果掩码的对应项为True):

x = ma.array([1, 2, 3], mask=[0, 0, 1])
x[0]

1

x[-1]

masked

x[-1] is ma.masked

True
如果掩码数组有命名空间,则从中获取一个元素和多维数组的返回机制相同:

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

(1, 2)

y[-1]

(3, --)
当从掩码数组中获取一个切片时,其返回值仍然是掩码数组,并且为原数组的一个视图。返回数组的mask既不是nomask(如果原始数组中没有无效数据),也不是原始数组mask的一个副本。所以在切片时最好做深拷贝,以防止对切片数据修改的同时也修改了原始数组。

x = ma.array([1, 2, 3, 4, 5], mask=[0, 1, 0, 0, 1])
mx = x[:3]
mx

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

mx[1] = -1
mx

masked_array(data=[1, -1, 3],
mask=[False, False, False],
fill_value=999999)

x.mask                        # 切片数据的修改影响到了原始数据,所以应该深拷贝

array([False, False, False, False, True])

x.data

array([ 1, -1, 3, 4, 5])

使用结构化数据类型访问掩码数组的字段将返回一个掩码数组MaskedArray

对掩码数组进行操作


掩码数组支持数学运算和逻辑运算。掩码数组中的无效数据将不参与运算,这意味着相应的数据项在操作前后应该不会发生改变。
注意:
我们应该强调掩码部分不发生改变的特性不是掩码数组自带的属性,在一些情况下掩码数值有可能在运算的过程中发生改变,所以用户不应该在运算过程中将掩码数值不变当作一个假设。
numpy.ma支持大多数的数学运算。对于一些有特定定义域的函数(例如logdivide),当运算结果为无效值时,返回masked常数:

ma.log([-1, 0, 1, 2])

masked_array(data=[–, --, 0.0, 0.6931471805599453],
mask=[ True, True, False, False],
fill_value=1e+20)

掩码数组也支持标准的numpy函数,输出为掩码数组。当函数的输入值被屏蔽时,函数不会对该部分进行计算。当输入值超出了函数的定义域,函数会返回掩码值:

x = ma.array([-1, 1, 0, 2, 3], mask=[0, 0, 0, 0, 1])
np.log(x)

masked_array(data=[–, 0.0, --, 0.6931471805599453, --],
mask=[ True, False, True, False, True],
fill_value=1e+20)

示例

利用特殊值表示缺失值


现在有一个列表x,其中用-9999.表示缺失值。我们想要计算这些数值的平均数并对其进行均值分析(每个值距离均值的偏差):

import numpy.ma as ma
x = [0.,1.,-9999.,3.,4.]
mx = ma.masked_values (x, -9999.)
print('掩码数组的均值为:{}'.format(mx.mean()))
print('每个值与均值的差值为:{}'.format(mx - mx.mean()))
print('每个值与均值的差值为:{}'.format(mx.anom()))

掩码数组的均值为:2.0
每个值与均值的差值为:[-2.0 -1.0 – 1.0 2.0]
每个值与均值的差值为:[-2.0 -1.0 – 1.0 2.0]

对缺失值进行填充


假设我们现在相对上一个数组进行打印,其中缺失值以均值进行替代。

print('用均值填充缺失值后的结果:{}'.format(mx.filled(mx.mean())))

用均值填充缺失值后的结果:[0. 1. 2. 3. 4.]

数值计算

在掩码数组中,我们无需担心缺失值便可进行数值计算,例如分母为0,对复数求平方根等等:

import numpy as np, numpy.ma as ma
x = ma.array([1., -1., 3., 4., 5., 6.], mask=[0,0,0,0,1,0])
y = ma.array([1., 2., 0., 4., 5., 6.], mask=[0,0,0,0,0,1])
print(np.sqrt(x/y))

[1.0 – -- 1.0 – --]
输出结果中有四个值为无效值,第一个是因为对负数取平方根,第二个是因为除0,最后两个是因为输入值被掩码。

忽略极端值


假设我们有一个数组d,其元素为0到1之间随机的浮点数。我们想对其[0.1, 0.9]区间范围内的值取平均:

d = np.random.random(size=100)
print(ma.masked_outside(d, 0.1, 0.9).mean())

0.46533658283140283

github链接
https://github.com/wzy6642/numpy-translate

numpy.ma详解相关推荐

  1. [转载] numpy.ma详解

    参考链接: Python中的numpy.asanyarray numpy.ma numpy.ma模块 基本原理 当数组元素包括缺失值或异常值时,该数组被称为掩码数组.numpy.ma模块的工作方式可以 ...

  2. Numpy.array()详解 、np.array与np.asarray辨析、 np.array和np.ndarry的区别

    记录一下numpy.array()的详细用法,以及与np.asarray()和np.ndarray()的区别. 目录 1. Numpy.array()详解 1.1 函数形式 1.2 参数详解 1.3 ...

  3. 【Numpy乘法详解】np.multiply()、np.matmul()、np.dot()等

    [Numpy乘法详解(代码示例)]np.multiply().np.matmul().np.dot()等 文章目录 [Numpy乘法详解(代码示例)]np.multiply().np.matmul() ...

  4. Numpy.array()详解

    1. Numpy.array()详解 该函数的作用一言蔽之就是用来产生数组. 1.1 函数形式 numpy.array(object, dtype=None, copy=True, order='K' ...

  5. 一文速学-时间序列分析算法之移动平均模型(MA)详解+Python实例代码

    目录 前言 一.移动平均模型(MA) 模型原理 自回归 移动平均模型 自相关系数 常用的 MA 模型的自相关系数 通用: MA(1)模型: MA(2)模型: 自协方差函数 二.Python案例实现 平 ...

  6. numpy.concatenate详解

    numpy.concatenate 用例: numpy.concatenate((a1, a2, -), axis=0, out=None) 功能: 沿着指定的轴拼接一系列数组. 参数 变量名 数据类 ...

  7. python引用numpy出错_引用numpy出错详解及解决方法

    numpy出错 解决方案 Problem: how to import numpy in subdirectory? Import error of numpy within subfolder. 错 ...

  8. numpy.ones() 详解

    函数原型: numpy.ones(shape, dtype=None, order='C') 参数介绍: shape:int或int的序列,为新数组的形状:如果我们仅指定一个int变量,则将返回一维数 ...

  9. numpy.sum详解

    numpy.sum 用例: numpy.sum(a, axis=None, dtype=None, out=None, keepdims=) 功能: 数组沿着指定的轴求和. 参数 变量名 数据类型 功 ...

最新文章

  1. ANDROID_NDK的path,如何在Android Studio中设置NDK_PROJECT_PATH
  2. C语言实现斐波那契搜索Fibonacci search算法(附完整源码)
  3. 检索数据_7_拼接列的值
  4. 程序员过关斩将--Http请求中如何保持状态?
  5. 厉害了!Spring Boot 2.5正式发布
  6. css专业名词,CSS进阶系列一(flex布局基础知识——介绍、规范、主要思想、专业术语)...
  7. 阿里巴巴四十大盗教你零知识证明
  8. 安卓小程序——猜数字游戏
  9. sobol灵敏度分析matlab_灵敏度分析 使用MATLAB编写
  10. 《Python数据分析基础教程:NumPy学习指南(第2版)》笔记8:第三章 常用函数4——线性模型、数组修剪与压缩、阶乘
  11. 金融之期货软件搭建,股票平台搭建,融资融券平台搭建
  12. mysql上机实验报告_数据库上机实验7实验报告.doc
  13. C#基于WindowsMediaPlayer实现音视频文件播放器
  14. 对话姜老师,DBA的职场之路
  15. android源生Browser分析---APP层基本架构
  16. Python实现的免费pdf阅读器
  17. 杂谈之WEB前端project师身价
  18. Java面向对象-final类和final方法、final变量(常量)
  19. MATLAB中的复杂矩阵输入问题
  20. 使用Go开发的数字书架应用 | Gopher Daily (2021.07.05) ʕ◔ϖ◔ʔ

热门文章

  1. 剑指offer:合并两个有序的链表
  2. python编程django项目中ModuleNotFoundError: No module named ‘django.core.urlresolvers‘解决方法
  3. 学生信息管理C语言 密码,求学生信息管理系统C语言版
  4. linux内核色彩管理,如何在Linux的色彩管理中获得标准结果
  5. linux nginx漏洞修复,nginx-1.14.1 和 nginx-1.15.6 发布,修复HTTP/2和MP4模块中的漏洞
  6. mysql中怎样扑抓到是那个字段出错_mysql 常见的几个错误问题
  7. java编程pig编码_Pig编程指南.pdf
  8. 间接寻址级别不同_详解西门子间接寻址之地址寄存器间接寻址
  9. python爬取有道词典_利用Python3和Charles爬取有道词典,生成翻译exe单文件
  10. 资源共享冲突问题概述