江大白 | 万字长文图解Numpy教程,看这一篇就够了!

news2024/11/17 19:44:54

本文来源公众号“江大白”,仅用于学术分享,侵权删,干货满满,有超级详细的图解。

原文链接:万字长文图解Numpy教程,看这一篇就够了! (qq.com)

以下文章来源于博客:Medium

作者:Lev Maximov

编辑:笑傲算法江湖

链接:https://betterprogramming.pub/numpy-illustrated-the-visual-guide-to-numpy-3b1d4976de1d

图片

导读

NumPy是Python的最重要的扩展程序库之一,也是入门机器学习编程的必备工具。然而对初学者来说,NumPy的大量运算方法非常难记。最近,国外有位程序员将NumPy的基本运算以图解的方式写下来,让学习过程变得轻松有趣。在Reddit机器学习社区发布不到半天就收获了500+赞。

下面就让我们跟随他的教程一起来学习吧!

教程内容分为向量 (一维数组)矩阵 (二维数组)三维与更高维数组3个部分。

1 Numpy数组与Python列表

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

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

两者有很多相似之处,以下是二者在运算时的一个示例:

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

更紧凑,尤其是在一维以上的维度;向量化操作时比Python列表快,但在末尾添加元素比Python列表慢。

△在末尾添加元素时,Python列表复杂度为O(1),NumPy复杂度为O(N)

2 向量运算

2.1 向量初始化

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

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

因此,常见的做法是定义一个Python列表,对它进行操作,然后再转换为NumPy数组,或者用np.zeros和np.empty初始化数组,预分配必要的空间:

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

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

在NumPy中,可以用arange或者linspace来初始化单调序列数组:

如果需要类似[0., 1., 2.]的浮点数组,可以更改arange输出的类型:arange(3).astype(float)。

但是有更好的方法:arange函数对数据类型敏感,如果将整数作为参数,生成整数数组;如果输入浮点数(例如arange(3.)),则生成浮点数组。

但是arange在处理浮点数方面并不是特别擅长:

这是因为0.1对于我们来说是一个有限的十进制数,但对计算机而言却不是。在二进制下,0.1是一个无穷小数,必须在某处截断。

这就是为什么将小数部分加到步骤arange通常是一个不太好的方法:我们可能会遇到一个bug,导致数组的元素个数不是我们想要的数,这会降低代码的可读性和可维护性。

这时候,linspace会派上用场。它不受舍入错误的影响,并始终生成要求的元素数。出于测试目的,通常需要生成随机数组,NumPy提供随机整数、均匀分布、正态分布等几种随机数形式:

2.2 向量索引

一旦将数据存储在数组中,NumPy便会提供简单的方法将其取出:

上面展示了各式各样的索引,例如取出某个特定区间,从右往左索引、只取出奇数位等等。但它们都是所谓的view,也就是不存储原始数据。并且如果原始数组在被索引后进行更改,则不会反映原始数组的改变。

这些索引方法允许分配修改原始数组的内容,因此需要特别注意:只有下面最后一种方法才是复制数组,如果用其他方法都可能破坏原始数据:

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

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

如上所述,布尔索引也会改写数组。它有两个常见的函数,分别是np.where和np.clip:

2.3 向量运算

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

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

△ 和Python中一样,a//b表示div b(整除),x**n表示xⁿ 向量还可以与标量进行类似的运算,方法相同:

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

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

我们也可以进行三角函数、反三角函数、求斜边运算:

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

△ floor取下界;ceil取上界;round为四舍六入五取偶

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

不过排序函数的功能比Python列表对应函数更少:

2.4 搜索向量中的元素

与Python列表相反,NumPy数组没有index方法。

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

  • 更快的方式是通过Numba中的next((i[0] for i, v in np.ndenumerate(a) if v==x), -1)来加速。

  • 一旦对数组进行排序,情况就会变得更好:v = np.searchsorted(a, x); return v if a[v]==x else -1的复杂度为O(log N),确实非常快,但是首先需要O(N log N)的排序时间。

2.5 比较浮点数

函数np.allclose(a, b)用于比较具有给定公差的浮点数组:

  • np.allclose假设所有的比较数字的等级是1个单位。例如在上图中,它就认为1e-9和2e-9相同,如果要进行更细致的比较,需要通过atol指定比较等级1:np.allclose(1e-9, 2e-9, atol=1e-17) == False。

  • math.isclose进行比较没有假设前提,而是基于用户给出的一个合理abs_tol值:math.isclose(0.1+0.2–0.3, abs_tol=1e-8) == True。

除此之外np.allclose在绝对和相对公差公式中还存在一些小问题,例如,对某些数存在allclose(a, b) != allclose(b, a)。这些问题已在math.isclose函数中得到解决。

3 矩阵运算

NumPy中曾经有一个专用的类matrix,但现在已弃用,因此下面将交替使用矩阵和2D数组两个词。

矩阵初始化语法与向量相似:

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

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

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

和一维数组一样,上图的view表示,切片数组实际上并未进行任何复制。修改数组后,更改也将反映在切片中。

3.1 axis参数

在许多操作(例如求和)中,我们需要告诉NumPy是否要跨行或跨列进行操作。为了使用任意维数的通用表示法,NumPy引入了axis的概念:axis参数实际上是所讨论索引的数量:第一个索引是axis=0,第二个索引是axis=1,等等。

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

3.2 矩阵运算

除了普通的运算符(如+,-,*,/,//和**)以元素方式计算外,还有一个@运算符可计算矩阵乘积:

在第一部分中,我们已经看到向量乘积的运算,NumPy允许向量和矩阵之间,甚至两个向量之间进行元素的混合运算:

3.3 行向量与列向量

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

默认情况下,一维数组在二维操作中被视为行向量。因此,将矩阵乘以行向量时,可以使用(n,)或(1,n),结果将相同。

如果需要列向量,则有转置方法对其进行操作:

能够从一维数组中生成二位数组列向量的两个操作是使用命令reshape重排和newaxis建立新索引:

这里的-1参数表示reshape自动计算第二个维度上的数组长度,None在方括号中充当np.newaxis的快捷方式,该快捷方式在指定位置添加了一个空axis。

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

根据规则,一维数组被隐式解释为二维行向量,因此通常不必在这两个数组之间进行转换,相应区域用灰色标出。

3.4 矩阵操作

连接矩阵有两个主要函数:

这两个函数只堆叠矩阵或只堆叠向量时,都可以正常工作。但是当涉及一维数组与矩阵之间的混合堆叠时,vstack可以正常工作:hstack会出现尺寸不匹配错误。

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

堆叠的逆向操作是分裂:

矩阵可以通过两种方式完成复制:tile类似于复制粘贴,repeat类似于分页打印。

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

逆运算为插入:

append就像hstack一样,该函数无法自动转置一维数组,因此再次需要对向量进行转置或添加长度,或者使用column_stack代替:

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

3.5 Meshgrid

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

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

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

但是实际上,在NumPy中有一种更好的方法。无需在整个矩阵上耗费存储空间。仅存储大小正确的矢量就足够了,运算规则将处理其余的内容:

在没有indexing=’ij’参数的情况下,meshgrid将更改参数的顺序:J, I= np.meshgrid(j, i)—这是一种“ xy”模式,用于可视化3D图。

除了在二维或三维数组上初始化外,meshgrid还可以用于索引数组:

3.6 矩阵统计

就像之前提到的统计函数一样,二维数组接受到axis参数后,会采取相应的统计运算:

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

all和any两个函数也能使用axis参数:

3.7 矩阵排序

尽管axis参数对上面列出的函数很有用,但对二维排序却没有帮助:

axis绝不是Python列表key参数的替代。不过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))]:先通过第2列排序,再通过第5列排序;

  • a[np.lexsort(np.flipud(a.T))]:按从左到右所有列依次进行排序。

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

4、因为这个特殊的操作方式更具可读性和它可能是一个更好的选择,这样做的pandas不易出错:

  • pd.DataFrame(a).sort_values(by=[2,5]).to_numpy():通过第2列再通过第5列进行排序。

  • pd.DataFrame(a).sort_values().to_numpy():通过从左向右所有列进行排序

4 高维数组运算

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

第一个索引是平面的编号,然后才是在该平面上的移动:

这种索引顺序很方便,例如用于保留一堆灰度图像:这a[i]是引用第i个图像的快捷方式。

但是此索引顺序不是通用的。处理RGB图像时,通常使用(y,x,z)顺序:前两个是像素坐标,最后一个是颜色坐标(Matplotlib中是RGB ,OpenCV中是BGR ):

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

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

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

△RGB图像数组(为简便起见,上图仅2种颜色)

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

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

这种转换没有实际的复制发生。它只是混合索引的顺序。

混合索引顺序的另一个操作是数组转置。检查它可能会让我们对三维数组更加熟悉。

根据我们决定的axis顺序,转置数组所有平面的实际命令将有所不同:对于通用数组,它交换索引1和2,对于RGB图像,它交换0和1:

有趣的是,(和唯一的操作模式)默认的axes参数颠倒了索引顺序,这与上述两个索引顺序约定都不相符。

最后,还有一个函数,可以在处理多维数组时节省很多Python循环,并使代码更简洁,这就是爱因斯坦求和函数einsum:

文章结束,感谢阅读。大家有推荐的公众号可以评论区留言,共同学习,一起进步。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1410868.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

周鸿祎回应坚定支持华为:因为 360 也被制裁了

在昨天的华为鸿蒙生态千帆启航仪式上&#xff0c;360集团创始人兼CEO周鸿祎发表演讲表示&#xff0c;360坚定地支持华为的决定源于双方都曾遭到制裁。周鸿祎在演讲中提到&#xff1a;“在华为最早被制裁的时候&#xff0c;我们是少数几个公开站出来坚定支持华为的公司。其实也很…

transformer详解

transformer详解 1.从全局角度概括transformer2.位置编码详细解读3.注意力机制4.残差连接5.Batch Normal6.layer normal7.decode 1.从全局角度概括transformer 一个典型的编码器-解码器的结构&#xff0c;类似于sequence-to-sequence 这6&#xff08;可以自己定&#xff09;个…

接口文档swagger2的使用

Spring-接口文档swagger2 1、swagger/knife4j 接口文档配置 ​ knife4j是swagger的增强版本&#xff0c;更加的小巧、轻量&#xff0c;功能也是更加的完善&#xff0c;UI也更加的清晰&#xff1b;可以从swagger到knife4j无缝切换。 1.1 引入相关依赖 <!--接口文档的开发:…

FastDeploy项目简介,使用其进行(图像分类、目标检测、语义分割、文本检测|orc部署)

FastDeploy是一款全场景、易用灵活、极致高效的AI推理部署工具&#xff0c; 支持云边端部署。提供超过 &#x1f525;160 Text&#xff0c;Vision&#xff0c; Speech和跨模态模型&#x1f4e6;开箱即用的部署体验&#xff0c;并实现&#x1f51a;端到端的推理性能优化。包括 物…

Django从入门到精通(三)

目录 七、ORM操作 7.1、表结构 常见字段 参数 示例 7.2、表关系 一对多 多对多 第一种方式 第二种方式 7.3、连接MYSQL 7.4、数据库连接池 7.5、多数据库 读写分离 分库&#xff08;多个app ->多数据库&#xff09; 分库&#xff08;单app&#xff09; 注意…

坚持刷题 | 平衡二叉树

文章目录 题目考察点代码实现实现总结对实现进一步改进扩展提问 坚持刷题&#xff0c;老年痴呆追不上我&#xff0c;今天继续二叉树&#xff1a;平衡二叉树 题目 110.平衡二叉树 考察点 递归能力&#xff1a; 能否使用递归来解决问题。树的基本操作&#xff1a;能否正确地访…

10.Elasticsearch应用(十)

Elasticsearch应用&#xff08;十&#xff09; 1.为什么需要聚合操作 聚合可以让我们极其方便的实现对数据的统计、分析、运算&#xff0c;例如&#xff1a; 什么品牌的手机最受欢迎&#xff1f;这些手机的平均价格、最高价格、最低价格&#xff1f;这些手机每月的销售情况如…

常用电子器件学习——光耦

光耦介绍 光耦合器一般由三部分组成&#xff1a;光的发射、光的接收及信号放大。 输入的电信号驱动光发射源&#xff0c;使之发光&#xff0c;被光探测器接收而产生光电流&#xff0c;再经过进一步放大后输出。这就完成了电—光—电的转换&#xff0c;从而起到输入、输出、隔离…

Ubuntu 22.04安装Nginx负载均衡

君衍. 一、编译安装Nginx二、轮询算法实现负载均衡三、加权轮询算法实现负载均衡四、ip_hash实现负载均衡 一、编译安装Nginx 这里我们先将环境准备好&#xff0c;我使用的是Ubuntu22.04操作系统&#xff1a; 这个是我刚安装好的&#xff0c;所以首先我们进行保存快照防止安装…

APP出海广告变现对接Admob

AdMob成立于2006年&#xff0c;并于2009年被Google收购。从那以后&#xff0c;AdMob在游戏及应用广告变现的重要性不断上升。凭借Google的血统&#xff0c;AdMob广告网络拥有其他广告平台不具备的优势&#xff1a;它可以访问无数的Google广告客户数据库。不仅如此&#xff0c;A…

线性代数速通

二---矩阵 逆矩阵 抽象矩阵求逆 数字型矩阵求逆 二阶矩阵求逆秒杀 解矩阵方程 方阵 伴随矩阵 三---向量组的线性相关性 线性表示 数字型向量组 线性相关性判断 抽象型向量组 线性相关性判断 向量组的秩与极大无关组 四---线性方程组 齐次方程组 基础解系 通解 非齐…

数学建模绘图

注意&#xff1a;本文章旨在记录观看B站UP数模加油站之后的笔记文章&#xff0c;无任何商业用途~~ 必备网站 以下网站我都试过&#xff0c;可以正常访问 配色&#xff08;取色&#xff09;网站&#xff1a; Color Palettes Generator and Color Gradient Tool Python&#x…

【论文阅读笔记】Towards Universal Unsupervised Anomaly Detection in Medical Imaging

Towards Universal Unsupervised Anomaly Detection in Medical Imaging arxiv&#xff0c;19 Jan 2024 【开源】 【核心思想】 本文介绍了一种新的无监督异常检测方法—Reversed Auto-Encoders (RA)&#xff0c;旨在提高医学影像中病理检测的准确性和范围。RA通过生成类似健…

1990-2019年城市维度区域创新创业指数面板数据/地级市创新创业指数面板数据

1990-2019年城市维度区域创新创业指数面板数据/地级市创新创业指数面板数据 1、时间&#xff1a;1990-2019年 2、范围&#xff1a;地级市&#xff08;290&#xff09; 3、指标&#xff1a;序号、年份、城市码、城市、总维度&#xff1a;总量指数得分、人均得分、单位面积得分…

《WebKit 技术内幕》学习之十(4): 插件与JavaScript扩展

4 Chromium扩展机制 4.1 原理 Chromium的扩展&#xff08;Extension&#xff09;机制 (1) 原先是Chromium推出的一项技术&#xff0c;该机制能够扩展浏览器的能力&#xff0c;例如笔者使用的一个扩展实例名为“switchy proxy”&#xff0c;它可以帮助用户方便的切换Chromium…

阿里云服务器4核16G3M32.25元,4核32G10M113.24元深度测评与购买建议

2024年1月24日&#xff0c;阿里云再次为用户带来了惊喜&#xff0c;推出了两款极具性价比的特价云服务器。其中&#xff0c;4核16G3M带宽的特惠价格仅为32.25元/月、96.75元/3个月&#xff0c;而4核32G10M带宽的特惠价格也仅为113.24元/月、339.72元/3个月。那么&#xff0c;这…

Redis性能运行参数的监测工具 - WGCLOUD

WGCLOUD是一款开源免费的运维监控平台&#xff0c;可以监测Redis的运行情况&#xff0c;比如redis的Key数量&#xff0c;过期Key数量&#xff0c;Redis的端口号&#xff0c;Redis的版本&#xff0c;同步状态&#xff0c;集群模式&#xff0c;使用内存等等数据 中间件Redis监测…

java基础:随机生成几个整数存放到数组里并按顺序输出案例分析

思路分析 具体步骤如下&#xff1a; 创建一个数组&#xff0c;用于存放生成的随机数。 定义最大值和最小值&#xff0c;用于限定随机数的取值范围。 使用循环和Random类中的方法生成随机数&#xff0c;并将其添加到数组中。 使用Arrays类中的sort()方法对数组进行排序&#…

牛客——都别吵吵了,我才是签到(质因数分解和统计质因数次数)

链接&#xff1a;登录—专业IT笔试面试备考平台_牛客网 来源&#xff1a;牛客网 题目描述 陶陶刚上一年级&#xff0c;今天数学课上老师教了乘法和除法&#xff0c;老师留了一道课后习题&#xff0c;陶陶很快地写完了&#xff0c;现在想请你帮助他检查一下是否和答案一致。…

应急响应红蓝工程师白帽子取证Linux和windows入侵排查还原攻击痕迹,追溯攻击者,以及各种木马和病毒以及恶意脚本文件排查和清除

应急响应红蓝工程师白帽子取证Linux入侵排查还原攻击痕迹,追溯攻击者,以及各种木马和病毒以及恶意脚本文件排查和清除。 一般服务器被入侵的迹象,包括但不局限于:由内向外发送大量数据包(DDOS肉鸡)、服务器资源被耗尽(挖矿程序)、不正常的端口连接(反向shell等)、服务…