Python:numpy.ma模块
翻译总结自:The numpy.ma module — NumPy v1.21 Manual
前言
ma是Mask的缩写,关于Mask的解释,如果有PS的基础,可以理解为蒙版,如果有计算机网络的基础,可以理解为掩码。Mask array是专门用于提取数组中特定元素构成的新数组的中间数组。
类比的话,如果说原数组是一块棋盘,每个位置都写了特定数字,那么Mask array就是和原棋盘大小相同的一块布,只是上边有几个洞。那么,把这块布盖在棋盘上,就只能显示出这几个洞处的数字了,其他位置上的数字都被蒙上了,显示的结果就是对原数组进行Mask的结果,这块布就是Mask。
原理
Masked array(就是前言中所写的棋盘,即原数组)中可能存在缺省值或非法值。numpy.ma
模块提供了一个类似于numpy工作模式的Masked array。
注意区分Masked array与Mask array的差别,Masked array是原数组,Mask array是参与Mask的中间数组。
什么是Masked array?
在大多数情况下,数据集中可能包含有无效数据(比如空值、非法值)。numpy.ma
模块通过引入Masked array来解决这个问题。
Masked array并不是单个数组,而是①标准ndarray和②Mask array的组合。一个Mask array也可以是一个nomask
,在Mask array中,要么用空值代表了非法值,要么用布尔数组中的True和False指明哪些值有效和无效。
如果Masked中某个元素是无效的,那么它对应的Mask中的这个位置的元素就是True,说明这个元素需要被“蒙”起来;反之,有效元素的位置上,Mask array中就是False,这个元素就不会被“蒙”。
这就确保了,那些Masked元素不会被用于计算。
举个例子,假设我们有以下一个数据集:
import numpy as np
import numpy.ma as ma
x=np.array([1,2,3,-1,5])
如果第四个数据非法且需要Mask的,最简单的方法就是构造一个Masked array:
mx=ma.masked_array(x,mask=[0,0,0,1,0])
然后,我们就可以排除这个无效值再对正确的数据集进行统计分析了:
mx.mean() #均值
#2.75
numpy.ma
ma模块最主要的功能是MaskedArray
类,它是numpy.ndarray
的子类。关于这个类的属性和方法,可以通过看MaskedArray class来获取更多的细节。
import numpy as np
import numpy.ma as ma
如果要构造一个第二个元素是非法元素的数组,我们可以这样写:
y=ma.array([1,2,3],mask=[0,1,0])
如果要构造一个,所有与1.e20相差不多的值视为无效值的Masked array,可以这样写:
z=ma.masked_values([1.0,1.e20,3.0,4.0],1.e20)
此外,还有许多构造Masked array的方法,可以看Constructing masked arrays。
使用numpy.ma
1)构造Masked array
Masked array由两部分组成:①标准ndarray;②Mask array;两者尺寸相同。
有多种构造Masked array的方法:
- 直接引入
MaskedArray
类; - 两种Masked array构造器,
array
与masked_array
:
array(data[,dtype,copy,order,mask,...]) 最常用,直接用一个array和与之对应的mask进行构造 masked_array 等同于numpy.ma.core.MaskedArray - 其它方法(常用的被我用红色标注):
|
将一个array正常转化为masked array |
|
与asarray相同 |
|
无效值(NaN和inf)会被Mask,并且无效值会被填充为fill_value |
|
等于value的值会被Mask |
|
大于value的值会被Mask |
|
大于等于value的值会被Mask |
|
给定区间内的值会被Mask |
|
无效值(NaN和inf)会被Mask |
|
小于value的值会被Mask |
|
小于等于value的值会被Mask |
|
不等于value的值会被Mask |
|
完全等同于value(常用于String)的值会被Mask |
|
给定区间外的值会被Mask |
|
浮点值相等的值会被Mask |
|
符合条件的下标/索引会被Mask |
2)访问数据
Masked array中的data array可以通过多种方式访问:
- 通过data属性;输出结果是一个
numpy.ndarray
(或子类)的视图:m.data - 通过__array__方法;输出结果是一个
numpy.ndarray
。 - 通过getdata函数。
通常情况下,需要先把其中无效数据通过filled
方法填充后,才能通过以上方法进行访问。
3)访问Mask
访问Mask array可以用 mask
属性:m.mask。一定要注意,Mask中的True代表着Masked array中的无效数据。
另外两种访问Mask的方法是通过getmask
和 getmaskarray
方法:
- getmask(x)要么返回Mask array,要么返回
nomask
。 - getmaskarray(x)要么返回Mask array,要么返回全是False的布尔数组。
4)访问合法元素
①~mask
如果我们要提取合法元素,我们可以用~mask作为索引:
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)
提取结果是MaskedArray,只是data全是合法元素,mask全是False。
②compress
另一种提取合法元素的方法是用compressed
,它只返回由合法元素组成的ndarray:
x.compressed()
array([1, 4])
需要注意compressed
的输出总是一维数组。
5)调整Mask
①Mask特定元素
a、直接标记特定元素为masked(推荐)
如果想把Masked array中的某个或某些元素手动标记为无效元素,推荐方法是直接把这个元素修改为 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)
b、修改Mask array
x = ma.array([1, 2, 3])
x.mask = [0, 1, 0]#修改mask
x
masked_array(data=[1, --, 3],
mask=[False, True, False],
fill_value=999999)
②取消Mask特定元素
a、直接给特定元素赋值(合法值)
x = ma.array([1, 2, 3], mask=[0, 0, 1])
x[-1] = 5 x
masked_array(data=[1, 2, 5],
mask=[False, False, False],
fill_value=999999)
这种方法对于hard mask会失效,一个array是否是hard mask,可以通过属性hardmask查看。
可以通过soften_mask
来把hard mask变为soft mask,也可以通过harden_mask
把它变成hard mask。
b、取消全部元素的Mask
在mask不是hard mask的前提下,可以通过把mask设置为nomask
来取消全部元素的mask。
x = ma.array([1, 2, 3], mask=[0, 0, 1])
x.mask = ma.nomask
x
masked_array(data=[1, 2, 3],
mask=[False, False, False],
fill_value=999999)
6)索引和切片
由于MaskedArray是ndarray的子类,所以它也继承了ndarray的索引和切片机制。
①索引
通过索引访问MaskedArray单个元素时,如果MaskedArray是一维的,那么输出结果要么是正常元素(Mask中该元素是False时),要么是一个特殊的值——masked
(Mask中该元素是True时):
x = ma.array([1, 2, 3], mask=[0, 0, 1])
x[0] #正常元素 Mask为False
1
x[-1] #特殊元素 Mask为True
masked x[-1] is ma.masked
True
如果MaskedArray是多维的,那么通过一个索引访问时,会列出该维度下的所有数据(除了Mask为False的元素):
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, --)
②切片
通过切片访问MaskedArray时,会返回一个新的MaskedArray,它的data和mask是由原MaskedArray的data和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])
7)Masked Array相关操作与运算
Masked Array支持一系列的算术和比较运算。无效数据通常不会参与运算,这意味着运算前后data的样式应该是一样的(有效的还是有效,无效的还是无效)。
numpy.ma
模块中实现了数组运算的大部分函数,有些一元或者二元函数(比如log
和divide
)在对某些值进行操作时,可能导致结果出现无效值(比如log(0)、log(-1)等):
ma.log([-1, 0, 1, 2])
masked_array(data=[--, --, 0.0, 0.6931471805599453],
mask=[ True, True, False, False],
fill_value=1e+20)
Masked Array也支持标准numpy函数,输出也是Masked Array。
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)
例子
1)用某个特定值代替无效值的Array
考虑一个List x,其中存放一系列元素,用-9999代替无效值。
我们希望①计算这些元素的平均值;②计算这些元素与平均值间的差值(以上计算都不包含无效值)。
import numpy.ma as ma
x = [0.,1.,-9999.,3.,4.] mx=ma.masked_values(x,-9999.)#构造Masked Array,标记-9999为无效值 #计算平均值
print(mx.mean())
2.0 #计算差值
print(mx - mx.mean())
[-2.0 -1.0 -- 1.0 2.0]
print(mx.anom())
[-2.0 -1.0 -- 1.0 2.0]
2)填充无效值
还以1)为背景,假设我们想把无效值填充为有效值的平均值:
print(mx.filled(mx.mean()))
[ 0. 1. 2. 3. 4.]
3)数学运算
数学运算时,会简单地不考虑无效值、除以0、对负值开根号等情况:
import 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(ma.sqrt(x/y))
[1.0 -- -- 1.0 -- --]
如果出现以上所说情况,会把这些情况的结果视为无效值。
4)忽略极端值
假设我们有一个array d,其中的元素都是位于(0,1)间的浮点值,我们想要计算d中位于[0.2,0.9]范围外值的平均值:
d = np.linspace(0, 1, 20) d_mean=d.mean() d_out=ma.masked_outside(d,0.2,0.9)#提取在[0.2,0.9]范围内的值
d_out_mean=d_out.mean() d_in_mean=d_mean-d_out_mean
-0.05263157894736836
Python:numpy.ma模块的更多相关文章
- python numPy模块 与numpy里的数据类型、数据类型对象dtype
学习链接:http://www.runoob.com/numpy/numpy-tutorial.html 官方链接:https://numpy.org/devdocs/user/quickstart. ...
- python基础——第三方模块
python基础——第三方模块 在Python中,安装第三方模块,是通过包管理工具pip完成的. 如果你正在使用Mac或Linux,安装pip本身这个步骤就可以跳过了. 如果你正在使用Window ...
- Python numpy中矩阵的用法总结
关于Python Numpy库基础知识请参考博文:https://www.cnblogs.com/wj-1314/p/9722794.html Python矩阵的基本用法 mat()函数将目标数据的类 ...
- [转]Python numpy函数hstack() vstack() stack() dstack() vsplit() concatenate()
Python numpy函数hstack() vstack() stack() dstack() vsplit() concatenate() 觉得有用的话,欢迎一起讨论相互学习~Follow Me ...
- 有关python numpy pandas scipy 等 能在YARN集群上 运行PySpark
有关这个问题,似乎这个在某些时候,用python写好,且spark没有响应的算法支持, 能否能在YARN集群上 运行PySpark方式, 将python分析程序提交上去? Spark Applicat ...
- ZH奶酪:【Python】random模块
Python中的random模块用于随机数生成,对几个random模块中的函数进行简单介绍.如下:random.random() 用于生成一个0到1的随机浮点数.如: import random ra ...
- python中的模块及包及软件目录结构规范
知识内容: 1.模块的定义与分类 2.模块的导入 3.模块与包 4.不同目录下的模块调用 一.模块的定义与分类 1.什么是模块 模块就是实现了某个功能的代码集合,模块是由一大堆代码构成的 类似于函数式 ...
- CS231n课程笔记翻译1:Python Numpy教程
译者注:本文智能单元首发,翻译自斯坦福CS231n课程笔记Python Numpy Tutorial,由课程教师Andrej Karpathy授权进行翻译.本篇教程由杜客翻译完成,Flood Sung ...
- Python的第三方模块安装
python的第三方模块安装一般使用python自带的工具pip来安装. 1.在Windows下,在安装python时勾选[安装pip]和[添加python至环境变量]. 如果在python安装目录的 ...
随机推荐
- 磁盘sda,hda,sda1,并行,串行
1.sd,hd表示硬盘, a表示第一块盘, 1表示硬盘上的第一个分区 2.sd是Serial ATA Disk ,表示硬盘是scsi,SATA串行接口 hd是 hard disk,表示硬盘是IDE(也 ...
- 扩容新生代为什么能够提高GC的效率
扩容新生代为什么能够提高GC的效率 该文章默认读者对JVM的基础有所了解 在学习JVM的时候,遇到了个人感觉比较有意思的问题,通过视频学习整理了一下. 先来上图: 大部分情况下,对象都会进入Eden区 ...
- python 小兵(12)模块1
序列化 我们今天学习下序列化,什么是序列化呢? 将原本的字典.列表等内容转换成一个字符串的过程就叫做序列化. 为什么要有序列化模块: 比如,我们在python代码中计算的一个数据需要给另外一段程序使用 ...
- 使用gdi+实时绘制picturebox(画个叉)
private void DrawReticle(System.Drawing.Point pt, int size)//画一个透明的前景图片上画十字 { Bitmap bmp = new Bitma ...
- Git标签 简单操作
感谢廖雪峰老师,以下内容多数来自老师的Git教程. 另有部分参考Git中文文档. 创建 命令git tag <tagname> [commit id]用于新建一个标签,默认为HEAD; 也 ...
- Window 共享内存
转载请注明来源:https://www.cnblogs.com/hookjc/ C++使用共享内存实现进程间通信文件映射是一种实现进程间单向或双向通信的机制.它允许两个或多个本地进程间相互通信.为了共 ...
- 深入分析Java中的关键字static
在平时开发当中,我们经常会遇见static关键字.这篇文章就把java中static关键字的使用方法的原理进行一个深入的分析.先给出这篇文章的大致脉络: 首先,描述了static关键字去修饰java类 ...
- 用curl发起https请求
使用curl发起https请求 使用curl如果想发起的https请求正常的话有2种做法: 方法一.设定为不验证证书和host. 在执行curl_exec()之前.设置option $ch = cur ...
- 解决sublime代码不提示的问题
如果想让sublime在你输入标签的过程中给你提示,需要按要求开启以下功能. 1.开启代码自动提示功能
- 获取联系人列表的时候contact_id出现null的值
因为删除联系人只是把它的contact_id设置为null,所以只要手机上删除过联系人id就会有null,用之前先判断是不是null就好了