当前位置:好爆料新闻网 >> 企业爆料 >> 从图片中学习NumPy:掌握N维数组的基本知识点 看这一本就够了

从图片中学习NumPy:掌握N维数组的基本知识点 看这一本就够了

发布于:2021-01-03 编辑:网友投稿

小茶整理整理

量子报告| QbitAI,微信官方账号

NumPy是Python最重要的扩展库之一,也是机器学习编程入门的必备工具。但是对于初学者来说,NumPy的无数算术方法是非常难记的。

最近有个外国程序员说NumPy的基本操作是图形化写下来的,学习过程轻松有趣。在Reddit机器学习社区发布后,不到半天就获得了500个赞。

让我们一起学习他的教程。

教程的内容分为三个部分:向量(一维数组)、矩阵(二维数组)和三维与更高维数组.

Numpy数组和Python列表

在介绍正式内容之前,我们先来了解一下Numpy数组和Python列表的区别。

乍一看,NumPy数组类似于Python列表。它们都可以作为容器使用,具有获取和设置元素以及插入和移除元素的功能。

它们之间有许多相似之处,下面是它们操作的一个例子:

与Python列表相比,Numpy数组具有以下特点:

更紧凑的,尤指在不止一个维度上;矢量化比Python列表快,但是在末尾添加元素比Python列表慢。

在末尾添加元素时,Python列表复杂度为O(1),NumPy复杂度为O(N)向量运算向量初始化

创建NumPy数组的一种方法是直接从Python列表中转换它们,数组元素的类型与列表元素的类型相同。

NumPy数组不能像Python列表那样加长,因为数组末尾没有保留空间。

因此,通常的做法是定义一个Python列表,对其进行操作,然后将其转换为NumPy数组,或者用np.zerosnp.empty,初始化该数组,并预先分配必要的空间:

有时我们需要创建一个与现有数组大小和元素类型相同的空数组:

事实上,用常量填充创建的数组的所有函数都有一个_like对应项来创建相同类型的常量数组:

在NumPy中,可以用arangelinspace:初始化单调序列数组

如果需要像[0]这样的浮点数组。 1. 2.],可以更改阿兰格的输出类型:阿兰格(3)。astype(float)。

但是有更好的办法:arange函数对数据类型敏感,如果取整数作为参数,则生成整数数组;如果一个浮点数(比如arange(3。))时,生成一个浮点数组。

但是阿兰格并不特别擅长处理浮点数:

这是因为0.1对我们来说是有限的十进制数,而对计算机来说不是。在二进制中,0.1是无限小数,必须在某处截断。

这就是为什么在步长中添加小数部分通常是一种糟糕的方式:我们可能会遇到一个错误,这导致数组中的元素数量不是我们想要的,这将降低代码的可读性和可维护性。

到时候,linspace就派上用场了。它不受舍入误差的影响,并且总是生成所需数量的元素。

出于测试目的,通常需要生成随机数组。NumPy提供了随机整数、均匀分布、正态分布等几种随机数:

向量索引

一旦数据存储在数组中,NumPy提供了一种简单的方法来获取它:

上面显示了各种索引,比如取出特定的区间,从右向左索引,只取出奇数位等等。

但都是所谓的视图,就是不存储原始数据。而如果原数组在被索引后发生了变化,则原数组的变化不会得到反映。

这些索引方法允许您分配和修改原始数组的内容,因此应该注意,只有下面的最后一种方法是复制数组,其他方法可能会破坏原始数据:

从NumPy数组中获取数据的另一种非常有用的方法是布尔索引,它允许各种逻辑运算符检索合格的元素:

注意:Python中的三进制比较3=a=5在NumPy数组中不起作用。

如上所述,布尔索引也会覆盖数组。它有两个共同的功能,即np.wherenp.clip:

向量运算

算术运算是NumPy速度最引人注目的地方之一。NumPy的向量运算符已经到了C级,避免了Python的慢循环。

NumPy允许像普通数字一样操作整个数组(加法、减法、乘法、除法、整数除法、幂):

,和Python一样,a//b代表div b,x**n代表x

向量也可以用与标量类似的方式操作:

大多数数学函数都有用于处理向量的NumPy对应物:

向量的点积和叉积也有运算符:

我们还可以执行三角函数、反三角函数和斜边计算:

数组可以四舍五入为整数:

楼层下限;Ceil取上界;四个房子,六进五,也要一轮

NumPy还可以执行以下基本统计操作(最大/最小、平均值、方差、标准差):

但是,排序功能比Python列表功能少:

搜索向量中的元素

与Python列表不同,NumPy数组没有索引方法。

查找元素的一种方法是np.where(a==x)[0][0],这既不优雅也不快速,因为要查找的项需要从头遍历数组的所有元素。

更快的方法是加速到下一个((I [0]对于NP中的I,v。nd enumerate (a) if v==x),-1) in Numba。

数组一旦排序,情况会变好:v=np.searchsorted(a,x);返回v的复杂度如果a[v]==x else -1是O(log N),真的很快,但是首先需要O(N log N)的排序时间。

比较浮点数

np.allclose(a, b)函数用于比较给定容差下的浮点数:

Np.allclose假设所有比较数的秩为1个单位。比如上图,它认为1e-9和2e-9是一样的。如果要做更详细的比较,需要通过环礁:NP指定比较级别1。Allclose (1e-9,2e-9,环礁==false。

Math.isclose没有任何假设,而是基于用户给出的一个合理的abs_tol值:Math。is close(0 . 10 . 20.3,ABS _ tol=1e-8)=true。

另外,np.allclose在绝对和相对容差公式上有一些小问题,比如有些数字有allclose(a,b)!=allclose(b,a).这些问题已经在数学中解决了。

矩阵运算

NumPy中曾经有一个特殊的类矩阵,现在已经废弃了,所以下面会交替使用矩阵和2D阵这两个词。

矩阵初始化语法类似于向量:

这里需要双括号,因为第二个位置参数是为dtype保留的。

随机矩阵的生成类似于向量的生成:

二维索引语法比嵌套列表更方便:

与一维数组一样,上面的视图显示切片数组实际上没有被复制。修改阵列后,更改也将反映在切片中。

轴参数

在很多运算中(比如求和),我们需要告诉NumPy是跨行还是跨列运算。为了使用任何维度的一般表示,NumPy引入了axis:的概念,轴参数实际上是所讨论的索引的数量:第一个索引是轴=0,第二个索引是轴=1,以此类推。

因此,在二维数组中,如果axis=0是按列,那么axis=1是按行。

矩阵运算

除了普通运算符(如-、*、/、//和* *)之外,还有一个计算矩阵乘积的@运算符:

第一部分,我们已经看到了矢量积的运算。NumPy允许向量和矩阵之间甚至两个向量之间的元素混合操作:

行向量和列向量

从上面的例子可以看出,在二维数组中,行向量和列向量被不同地处理。

默认情况下,一维数组在二维操作中被视为行向量。所以矩阵乘以行向量时,可以用(n,),或者(1,n),结果也是一样的。

如果需要列向量,可以使用转置方法对其进行操作:

可以从一维数组生成二进制数组列向量的两个操作是使用reshape重排和newaxis:命令创建新索引

此处的-1参数表示整形会自动计算第二维的数组长度,而无作为方括号中np.newaxis的快捷方式,在指定位置添加一个空轴。

因此,NumPy中有三种类型的向量:一维数组、二维行向量和二维列向量。这是两者之间显式转换的示意图:

根据规则,一维数组隐式解释为二维行向量,所以通常不需要在两个数组之间进行转换,对应的区域用灰色标注。

矩阵运算

连接矩阵有两个主要功能:

这两个函数在只叠加矩阵或向量时可以正常工作。但是,当涉及一维数组和矩阵的混合叠加时,vstack可以正常工作:hstack会有尺寸失配误差。

因为,如上所述,一维数组被解释为行向量而不是列向量。解决方法是将其转换为列向量,或者使用column_stack将其自动化:

堆叠的反向操作是拆分:

矩阵有两种复制方式:tile类似于复制粘贴,repeat类似于页面打印。

可以用delete:删除特定的列和行

反向操作是插入:

Append就像hstack一样,这个函数不能自动转置一维数组,所以需要再次转置或者给向量加上长度,或者用column_stack来代替:

事实上,如果我们需要做的只是在数组的边界上添加常量,那么pad函数就足够了:

网格

如果我们想要创建以下矩阵:

这两种方法都很慢,因为它们使用Python循环。在MATLAB中处理这类问题的方法是创建一个meshgrid:

meshgrid函数接受任何一组索引,mgrid只是一个切片,索引只能生成一个完整的索引范围。如上所述,提供的函数只使用I和J参数调用一次。

但其实NumPy还有更好的办法。不需要消耗整个矩阵上的存储空间。只存储正确大小的向量就够了,操作规则会处理剩下的:

没有索引='ij '参数,meshgrid会改变参数的顺序:j J,I=np.meshgrid(j,i)— j,I)-这是一个“xy”模式,用来可视化三维图像。

除了在2d或3d阵列上初始化之外,meshgrid还可用于索引阵列:

矩阵统计

就像前面提到的统计函数,接收到轴参数后,2D阵列会进行相应的统计运算:

在二维和更高维中,argmin和argmax函数返回最大值和最小值的索引:

轴参数也可由所有和任何功能使用:

矩阵排序

虽然轴参数对上面列出的函数很有用,但对二维排序没有帮助:

Axis绝不是Python列表关键参数的替代品。但是,NumPy有几个允许按列排序的功能:

1.根据第一列对数组进行排序:a[a[:0]。argsort]

argsort排序后,在此返回原始数组的索引数组。

这种方法可以重复,但必须注意避免下一个排序混淆前一个排序的结果:

a=a[a[:2]。argsort]

a=a[a[:1]。argsort(kind='stable')]

a=a[a[:0]。argsort(kind='stable')]

2.有一个辅助函数lexsort,它以上述方式对所有可用的列进行排序,但总是根据行执行它们,例如:

a【NP。lexsort (NP。flipud (a [2,5]。t)]:先按第二列排序,再按第五列排序;

A[np.lexsort(np.flipud(a.T))]:按从左到右的所有列排序。

3.还有一个参数顺序,但是如果从一个普通的(非结构化的)数组开始,既不快速也不容易使用。

4.因为这种特殊的操作模式可读性更强,可能是更好的选择,熊猫不容易出错:

警局。数据帧(a)。sort _ values (by=[2,5])。to _ numpy:按第2列排序,然后按第5列排序。

Pd.dataframe (a)。sort _ values.to _ numpy:按从左到右的所有列排序

高维数组运算

当通过重新排列一维向量或转换嵌套的Python列表来创建3D数组时,索引意味着(z,y,x)。

第一个指标是飞机的编号,然后是飞机上的运动:

这个索引顺序很方便,例如,保存一堆灰色图像:这个a[i]是引用ith图像的快捷方式。

然而,这种索引顺序并不具有普遍性。在处理RGB图像时,通常使用(y,x,z)的顺序:前两个是像素坐标,最后一个是颜色坐标(Matplotlib中的RGB和OpenCV中的BGR):

这样就可以方便地引用一个特定的像素:a[i,j]给出像素的RGB元组(I,j)。

因此,创建特定几何图形的实际命令取决于正在处理的域的约定:

显然,像hstack、vstack或dstack这样的NumPy函数并不知道这些约定。其中硬编码索引顺序为(y,x,z),RGB图像顺序为:

的RGB图像阵列(为简单起见,上图只有2种颜色)

如果数据布局不同,使用concatenate命令堆叠图像并在轴参数中提供显式索引号会更方便:

如果使用axis不方便,可以将数组转换成hstack的形式:

这种转换不会随着实际的复制而发生。它只是混合了索引的顺序。

混合索引顺序的另一种操作是数组转置。检查它可能会让我们更熟悉3D阵列。

根据我们决定的轴顺序,实际用于置换阵列所有平面的命令将会不同:对于一般阵列,它交换索引1和2,对于RGB图像,它交换索引0和1:

有趣的是,(也是唯一的操作模式)默认轴参数颠倒了索引顺序,这与上述两种索引顺序约定不一致。

最后还有一个功能,可以节省大量Python循环,在处理多维数组时,可以让代码更加简洁。这是爱因斯坦的求和函数einsum:

它沿着重复的索引对数组求和。

最后,如果你想掌握NumPy,可以去GitHub上的项目——100道NumPy练习题验证你的学习成绩。

原始链接:

https://medium.com/better-programming/numpy-pictured-the-visual-guide-to-numpy-3b1 d 4976 de 1d

100个NumPy练习:

https://github.com/rougier/numpy-100

————

本文是网易新闻网易特别内容奖励计划签约账号【qubit】的原创内容,未经账号授权,禁止随意转载。

AI落地最佳参考!

2020中国人工智能年度评选结果揭晓

12月16日,在qubit MEET 2021 Smart Future Conference上,50家领先企业、10家明星创业公司、30位商业领袖、10款最佳产品、10款最佳解决方案、5款社会责任模式、5款最佳技术社区等年度奖项全部揭晓。

点击图片查看完整列表:

量子位 QBITAI标题签名作者

跟踪人工智能技术和产品的新发展

一键三环“分享”“喜欢”“观看”

科技前沿的进步天天见面~

标签: 数组 向量 索引
猜你喜欢
最新文章
本类推荐
TOP 10