【深度学习基础】NumPy数组库的使用

目录

写在开头

 一、数组的类型与维度

数组的类型

数组的维度

二、数组的创建

递增数组 

同值数组

随机数数组 

三、数组的索引

访问/修改单个元素 

花式索引 

数组的切片

四、数组的变形

数组的转置

数组的翻转

数组的形状改变

数组的拼接

五、数组的运算 

 数组与常数的运算

数组与数组的运算 

六、数组的函数

线性代数中的矩阵乘法

数学函数 

聚合函数 

七、布尔型数组 

布尔型数组的生成  

布尔型数组的常用函数 

八、从NumPy数组到PyTorch张量 

写在最后 

写在开头

   近期好久不写博客了,主要是心态略有浮躁,同时对于自己的网络安全专业和未来方向也略显怀疑,可能还会迷茫一段时间,但我已经决定尽可能让自己忙碌起来,心态尽量平和,少受互联网信息的影响,避免过多思考人生与未来。至于这个新开的深度学习专栏的来由,主要是本人近期要开始研究写论文的东西,要选取一些深度学习模型对某种网络攻击类型进行检测,而我本人又对于深度学习的领域仅限于了解一些基础原理,实践能力(当调参侠)基本没有,因此我也从头开始慢慢学习,用博客做个记录。不过我相信慢就是快,一步一步脚踏实地慢慢来,也终将会有所进步。

   此处还特别感谢B站爆肝杰哥的视频,详解了配置pytorch环境的每一步。这里放上其视频链接(本文并不涉及到pytorch的内容,后续博客可能会用到):

Python深度学习:安装Anaconda、PyTorch(GPU版)库与PyCharm_哔哩哔哩_bilibili

  本文使用的NumPy库的版本为1.21,不过相近版本的语法都大差不差,基本可以通用。在进入深度学习具体算法的学习之前我们先介绍NumPy数组库,这是因为NumPy包为Python提供了数组变量的类型,弥补了Python本身数据类型的不足。虽然Python中的列表数据类型也可以实现数组的功能,但对于列表,其每个元素的数据类型是可以不同的,因此列表在存储元素的值的同时也要存储该元素的数据类型,这在一定程度上浪费了内存。而NumPy数组中的元素仅可容纳一种数据类型,存储时可以节约内存,加快运算速度,更方便深度学习的相关处理。下面我们做一个简单的引入:

import numpy as nparr1 = np.array([10, 20, 30])  # 创建整数型数组
arr2 = np.array([1, 2, 3.])   # 创建浮点型数组,内涵浮点数,即为浮点型数组
list1 = ["hello", 100, 3.14]   # 创建列表,元素的数据类型可以不同
print(arr1)
print(arr2)
print(list1)

 可看到NumPy数组与Python列表的不同:

1. Numpy数组的元素数据类型一致(可分为整数型数组和浮点型数组),而列表可以不一致。

2. Numpy数组用print输出后元素之间是没有逗号','的,而列表的元素之间有逗号','作为分隔。

 一、数组的类型与维度

数组的类型

    Numpy数组就两种类型,整数型/浮点型。其中可以用.astype()方法相互转换,示例如下:

arr1 = np.array([10, 20, 30])  # 创建整数型数组
arr2 = arr1.astype(float)    # 整数型转浮点型
arr3 = arr2.astype(int)      # 浮点型转整数型
print(arr1)
print(arr2)
print(arr3)

   另外通常情况下,整数型数组在运算过程中很容易升级为浮点型数组,只要与浮点数(组)做运算即可:

int_arr = np.array([10, 20, 30])   # 创建整数型数组
float_arr = np.array([1.0, 2, 3])  # 创建浮点型数组
print(int_arr + 0.0)  # 整数型数组与浮点数进行运算
print(int_arr * 1.0)
print(int_arr / 1)    # 除以整数也会升级为浮点型数组
print(int_arr + float_arr)

  这里特别注意整数型数组遇到除法(即使是➗整数),都会升级为浮点数组 

数组的维度

  基本上不会遇到三维以上的,数组的中括号层数反应了该数组的维度。这里列个表描述一维到三维数组的表示:

数组的维度及其表示
数组维数形状表示举例说明
一维x 或 (x,)一维数组[1 2 3]的形状是3 或 (3,)
二维(x, y)二维数组[[1 2 3]]的形状是(1, 3)
三维(x, y, z)三维数组[[[1 2 3]]]的形状是(1, 1, 3)

  可以使用.shape属性(注意没有括号,不是方法!)查看数组的形状,举例如下

   数组之间的相互转化,使用.reshape()方法即可,参数填写想要转换的维数,例如想把(2,3)的数组转化为(3, 2)的数组:

arr1 = np.array([[1, 2, 3], [4, 5, 6]])
print("转换前:\n",arr1)
arr2 = arr1.reshape((3, 2))
print("转化后:\n", arr2)

 特别注意的是,reshape()方法有个方便之处,就是给定了每个维度之后,它可以自动算出最后一个维度是多少,最后的这个维度可以填写-1,举例如下:

# 将2*15的二维数组(矩阵)转换为5*6
arr1 = np.arange(30).reshape(2,15)   # 生成2*15的整数递增数组 
print("转换前:\n",arr1)
arr2 = arr1.reshape(5, -1)  # 填写-1时,reshape会自动计算出此处应该是6
print("转化后:\n", arr2)

二、数组的创建

递增数组 

  直接用np.array()函数可以将Python列表转化为Numpy数组,这个方法我们已经实现过。另外还可以用np.arange()函数创建递增数组格式如下:

arr = np.arange([起始位置x], 终止位置y, [步长s] )

这个和python中的range函数类似,生成[x, y)范围内的数组。print()

同值数组

创建同值数组可以用np.zeros()创建全为0.0的数组,用np.ones()创建全为1.0的数组。

arr1 = np.ones(3)
print(arr1)
arr2 = 3.14 * np.ones((2,4))  # 创建全为3.14的2*4的矩阵
print(arr2)

随机数数组 

   创建随机数组成的数组,需要使用np.random系列的函数,下面举例说明:

   首先是0-1均匀分布,方法为np.random.random(形状),举例如下:

# 创建0-1范围均匀分布的矩阵
arr1 = np.random.random(5)
print(arr1)
# 创建90-100范围均匀分布
arr2 = (100-90)*np.random.random((2, 3)) + 90
print(arr2)

   

如果想生成整数型随机数组,则通过np.random.randint(min,max, shape)实现: 

# 创建[1, 10)范围内的整数随机数组,矩阵形状为2*3
arr3 = np.random.randint(1, 10, (2,3))
print(arr3)

 另外,服从正太分布的随机数组的创建方法是np.random.normal(μ, σ, shape):

# 创建均值为80,标准差为5的正太分布随机数组,矩阵形状为3*3
arr4 = np.random.normal(80, 5, (3,3))
print(arr4)

   特别地,如果只需要标准正太分布,则可直接使用np.random.randn(shape)即可,只需要传入形状参数。

三、数组的索引

访问/修改单个元素 

   这个和Python列表一致,正索引从0开始,倒索引从-1开始,就懒得具体描述了。注意对单一元素修改时,不会改变原本矩阵的类型(整数型/浮点型)即可

arr = np.arange(1, 10).reshape((3,-1))
print(arr)
arr[1,1] = 100.123  # 修改整形数组中的某个元素,数组依然为整形,该元素的浮点会被截断。
print(arr)

花式索引 

   用两层中括号可以进行花式索引,同时取出矩阵中的多个元素,输出仍然是个向量,举例如下:

arr = np.arange(1, 17).reshape((4,4))
print(arr)
# 花式索引,取出并修改副对角线的元素
print(arr[[0,1,2,3],[3,2,1,0]])

  利用这种方法,可以同时修改矩阵中的多个元素:

arr = np.arange(1, 17).reshape((4,4))
print(arr)
# 花式索引,取出并修改副对角线的元素
arr[[3,2,1,0],[0,1,2,3]] = (100,200,300,400)
print("修改后:\n", arr)

数组的切片

 这快其实完全可以类比Python中列表的切片,就简单举个例子略过好了:

# 生成10*10的矩阵
arr = np.arange(1, 101).reshape((10,-1))
print(arr)
# 取出第4-5行,4-5列
print("取出最中间的2*2:\n", arr[4:6, 4:6])

  这里还需要特别注意:数组的切片仅仅是视图,数组的赋值也仅仅是绑定,并没有产生新的数组! 

# 生成10*10的矩阵
arr = np.arange(1, 101).reshape((10,-1))
print(arr)
# 取出第4-5行,4-5列
arr2 = arr[4:6, 4:6]
arr3 = arr
arr2[:,:] = 999
print(arr)
print(arr2)
print(arr3)

  由上图可知,改了arr2后,arr和arr2也会改变,这是因为不论是切片还是赋值,其实都不会创建新的数组,本质上都是相同的内存!要想创建新的变量,需要用到.copy方法才可(实际用到的很少,此处略)。

四、数组的变形

数组的转置

  使用.T即可实现转置,注意转置操作仅对矩阵有效,如果是向量(一维数组)需要升级为矩阵(二维数组)

arr1 = np.arange(1, 5)
print("初始向量:\n", arr1)
# 升级为矩阵
arr2 = arr1.reshape((1,-1))
print("矩阵:\n", arr2)
print("转置后的结果\n", arr2.T)

数组的翻转

     一共两个函数,分别是上下(up-down)翻转np.flipud()和左右(left-right)翻转np.fliplr()。注意对于向量(一维数组),只能进行上下翻转。这是因为在数学中,向量是以列向量的形式存在。下面举例说明即可:

# 向量的翻转
vec = np.arange(10)
print("初始向量:\n", vec)
vec_ud = np.flipud(vec)
print("向量翻转后:\n", vec_ud)

   矩阵的翻转如下:

# 矩阵的翻转
mat = np.arange(25).reshape((5, -1))
print("初始矩阵:\n", mat)
mat_lr = np.fliplr(mat)
print("左右翻转:\n", mat_lr)
mat_ud = np.flipud(mat)
print("上下翻转:\n", mat_ud)

数组的形状改变

  使用.reshape()方法即可,前面用到多次了,这里不再举例。

数组的拼接

  使用函数np.concatenate([arr1, arr2])即可实现拼接,如果是向量(一维),直接拼接即可。如果是矩阵,默认情况按照axis=0进行拼接(要求列的维度相同),也可以指定按照另一个维度进行拼接,注意对应维度元素个数相等。向量不能和矩阵进行拼接,需要先升级为矩阵。

# 向量的拼接
vec1 = np.array([1,2,3])
vec2 = np.array([7,8,9])
vec3 = np.concatenate([vec1, vec2])
print(vec3)

  矩阵拼接要注意对齐相应维数:

# 矩阵的拼接
mat1 = np.array([[1,2,3], [4,5,6]])
mat2 = np.array([[7,8,9], [10,11,12]])
mat3 = np.concatenate([mat1, mat2])   #默认情况,axis=0
mat4 = np.concatenate([mat1, mat2], axis=1)   #非默认情况, 指定axis=1
print("axis=0拼接:\n", mat3)
print("axis=1拼接:\n", mat4)

五、数组的运算 

 数组与常数的运算

 这个其实没啥好说的,就是Python中的那些常见运算符,加减乘除幂余取整啥的,常见运算符如下:

+  =  *  /  **  //  % 

   这些运算就是对矩阵中的元素逐个运算,特别注意除法会生成浮点型数组即可。随便举两个例子

数组与数组的运算 

  这里也没太多可讲的,如果数组的维度相同,则数组间的运算就是对应元素的运算(并不是线性代数中的运算方式)。

  如果进行运算的数组的维数不同,则会出现某一方被广播的情况,例如:

1. 向量与矩阵运算,则向量自动升级为行矩阵。即如果是 (y,) 与 (x,y)运算,则(x,)会先升级为(1,y),然后再运算

2. 如果某矩阵是行矩阵或列矩阵,则该矩阵被广播,以适配另一个矩阵的形状。

   与这个例子类似,列矩阵也可以被广播:

   行矩阵和列矩阵也可以同时被广播,即(1,y)的行矩阵与(x,1)的列矩阵运算,相当于先把各自广播为(x, y),再进行运算:

六、数组的函数

线性代数中的矩阵乘法

  就是函数np.dot(arr1,arr2)。当arr1和arr2均为向量时,相当于是向量点积,其他情况都可视为线性代数中的矩阵乘法:

数学函数 

 有一大堆,这里列一下好了

函数说明
np.abs()绝对值
np.sin()正弦
np.cos()余弦
np.tan()

正切

np.exp()指数e*x
np.log()对数ln(x)

  举例说明一下对数函数吧,默认是以e为底,以其他为底的话需要用换底公式:

聚合函数 

  就是按照对应维度的方向求最大最小值,求和、平均值、标准差啥的。向量也可以,但向量没有axis参数,矩阵需要哪个用axis参数指明是哪个维度(当axis=0,最终结果的个数与每一行的元素个数相同。反之axis=1,最终结果的个数与每一列的元素个数相同)。列个表格:

函数说明
np.max(arr, axis=0),  np.min(arr, axis=1)按维度求最大或最小值
np.sum(arr, axis=0)按维度求和
np.mean(arr, axis=0), np.std(arr, axis=1)按维度最均值或标准差
# 聚合函数
arr = np.arange(1, 11).reshape((2, 5))
print(arr)
print("按照维度0求均值: ", np.mean(arr, axis=0))
print("按照维度1求均值: ", np.mean(arr, axis=1))
print("整体求均值: ", np.mean(arr))

特别注意:考虑到大型数组难免有缺失值,以上聚合函数碰到缺失值时会报错,因此出现了聚合函数的安全版本,即计算时忽略缺失值:np.nansum( )、 np.nanprod( ) 、np.nanmean( )、np.nanstd( )、np.nanmax( )、np.nanmin( )。

七、布尔型数组 

布尔型数组的生成  

顾名思义,就是每个元素都是布尔类型的数组,可以通过一些比较运算符产生(>, <, ==, !=, >=, <=)。这些于是奶奶是还可以多个条件同时使用(用与,或,非对应&, |, ~)下面举例说明:

# 布尔类型的产生
arr = np.arange(25).reshape(5,-1)
print(arr)
# 将值在(10, 18)范围内的位置置为True
print((arr>10)&(arr<18))
print("满足条件的个数为:", np.sum((arr>10)&(arr<18)))

布尔型数组的常用函数 

使用np.sum()函数可以统计布尔数组里True的个数,如上。另外还有两个常用函数,如下:

函数说明
np.sum(arr)统计布尔数组arr里True的个数
np.any(arr)arr中有一个是True,则为True,否则为False
np.all(arr)arr中所有的都是True, 才为True,否则为False
np.where(arr)返回arr中是True的位置

   这里可以举个例子,假设某次英语六级考试,10000人参加考试,所有人均分是425,标准差为70,进行一次模拟,判断是否所有的考生分数都>200,并找出高分的位置:

# 模拟六级成绩样本
arr = np.random.normal(425, 70, 10000)
# 判断是否所有人都高于200分
print(np.all(arr>200))
# 寻找高于650分的位置
print(np.where(arr>650))

八、从NumPy数组到PyTorch张量 

  PyTorch作为当前最常用的深度学习库,融合了NumPy数组的语法,作为处理张量的基本语法,且运算可用GPU加速,具有很大速度优势。NumPy数组和PyTorch张量有一定的对应关系:

1.np 对应 torch
2.数组 array 对应张量 tensor
3.NumPy n 维数组对应着 PyTorch n 阶张量
NumPy数组和PyTorch张量可用相互转化:
ts = torch.tensor(arr) 或  arr = np.array(ts)

   NumPy数组和PyTorch张量相关处理的不同点,基本上将np改为torch,array改为tensor,即可对应Pytorch的处理方法。不过也有少量不同,此处根据B站爆肝杰哥的总结,列举不同点(表格源于B站:爆肝杰哥)。

写在最后 

   这一章节是PyTorch深度学习的基础,内容还挺多的。后续我可能还会更新一些DNN,CNN,RNN,GNN相关的博客,由于我的研究课题是要选取一些深度学习模型对某种网络攻击类型进行检测,可能会用到图神经网络相关的内容,后续学习的过程也会重点总结一下。

   今年感觉状态稀碎,不过慢慢来,相信慢就是快!不要太过在意短期的得失。如果各位读者有什么问题也欢迎评论区指出,也可以私信与我讨论(也可以是技术无关的问题),我一定知无不言。

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

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

相关文章

Linux系统启动原理

Linux系统启动原理及故障排除 Centos6系统启动过程 修改系统启动级别 vim /etc/inittabCentos7启动流程 加载BIOS信息&#xff0c;进行硬件检测 根据BIOS设定读取设备中的MBR&#xff0c;加载Boot loader 加载内核&#xff0c;内核初始化以后以模块的形式动态加载硬件 并且加…

FFmpeg的流程

文章目录 前序代码结构FFmpeg.cffmpeg_opt.c 小结 前序 之前看过FFmpeg的各种命令&#xff0c;然后不是很理解。相信很多人都不是很理解&#xff0c;毕竟&#xff0c;单纯的去记住那些命令行本身就需要很大的内存&#xff0c;我们的大脑内存又有限&#xff0c;所以&#xff0c…

java “错误:编码GBK 的不可映射字符”

环境&#xff1a;JDK-17 本机编码&#xff1a;utf-8 代码编码&#xff1a;GBK 错误&#xff1a;java “错误&#xff1a;编码GBK 的不可映射字符” 解决1&#xff1a;记事本打开java源文件&#xff0c;另存为选择ANSI编码 解决2&#xff1a;复制代码再将编码格式改为utf-8,…

java欢迪迈手机商城设计与实现源码(springboot+vue+mysql)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的欢迪迈手机商城设计与实现。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 项目简介&#xff1a; 欢迪迈手机商城…

spring状态机实战

一、什么是状态机 状态机是有限状态自动机的简称&#xff0c;是现实事物运行规则抽象而成的一个数学模型&#xff0c;是一种概念性机器&#xff0c;它能采取某种操作来响应一个外部事件。这种操作不仅能取决于接收到的事件&#xff0c;还能取决于各个事件的相对发生顺序。状态…

不同网段的通信过程

这里的AA和HH指的是mac地址&#xff0c;上面画的是路由器 底下的这个pc1&#xff0c;或者其他的连接在这里的pc&#xff0c;他们的默认网关就是路由器的这个192.168.1.1/24这个接口 来看看通信的过程 1、先判断&#xff08;和之前一样&#xff09; 2、去查默认网关&#xf…

基于SpringBoot和Hutool工具包实现的验证码案例

目录 验证码案例 1. 需求 2. 准备工作 3. 约定前后端交互接口 需求分析 接口定义 4. Hutool 工具介绍 5. 实现验证码 后端代码 前端代码 6. 运行测试 验证码案例 随着安全性的要求越来越高&#xff0c;目前项目中很多都会使用验证码&#xff0c;只要涉及到登录&…

Liunx系统中修改文件的创建时间以及访问时间

在Linux系统中&#xff0c;可以使用touch命令来修改文件的时间戳。以下是一些常用的touch命令选项&#xff1a; &#xff08;其实在MacOS中也适用&#xff09; 修改访问时间&#xff08;Access Time&#xff09;和修改时间&#xff08;Modification Time&#xff09;&#xf…

Celery的Web监控工具Flower

1 简介Flower Flower官网 Flower是一个WEB端的监控工具&#xff0c;可以监控Celery的消费者。但是WEB端的监控对于监控系统来说&#xff0c;有个屁用&#xff0c;有用的是监控告警。还好Flower不是全部是垃圾&#xff0c;它提供的Prometheus的监控端点。然而。。。。。如何保证…

CorelCAD v2022.5 解锁版 安装教程(2D制图 3D设计和打印的简化软件)

前言 CorelCAD&#xff0c;加拿大Corel公司开发的一款适用于2D制图、3D设计和打印的简化版CAD软件。它是款专业的2D制图和3D设计软件&#xff0c;拥有行业标准文件兼容性&#xff0c;支持 .DWG、.STL、.PDF、 .CDR*等文件格式&#xff0c;轻松实现协作和项目共享&#xff0c;利…

学 Go 具体能干什么?

学习 Go (Golang) 后&#xff0c;你可以从事许多不同的工作和项目&#xff0c;Go 语言以其高性能、并发处理和简洁的语法而闻名&#xff0c;特别适合以下几个领域&#xff1a; 1. 后端开发 Go 在后端开发中非常流行&#xff0c;特别适合构建高性能的 Web 服务和 API。 Web 框…

【机器学习】基于核的机器学习算法(Kernel-based Algorithms):原理,应用与优化

&#x1f440;传送门&#x1f440; 文章引言&#x1f50d;&#x1f340;核函数的概念&#x1f680;基于核的算法原理&#x1f496;基于核的算法应用&#x1f41f;支持向量机&#xff08;SVM&#xff09;&#x1f4d5;核主成分分析&#xff08;KPCA&#xff09; &#x1f340;未…

大数据信用报告查询有哪些作用?哪个平台更好?

大数据信用是基于大数据技术&#xff0c;通过大数据系统生成的大数据信用报告&#xff0c;报告收集了查询人在非银环境下的申贷数据以及履约行为和信用风险的综合性报告。很多人都会问&#xff0c;大数据信用报告查询有哪些作用?哪个查询平台更好的疑问&#xff0c;下文就详细…

C++STL---string知识汇总

前言 我们现在开始CSTL的学习&#xff0c;从这时开始我们就要锻炼自己查看英文文档的能力&#xff0c;每种数据结构都有上百个接口函数&#xff0c;我们把他们全部记下来是不可能的&#xff0c;所以我们只记最常见的20几个接口&#xff0c;其他的大概熟悉有什么功能&#xff0…

深入JVM元空间以及弹性伸缩机制

个人博客 深入JVM元空间以及弹性伸缩机制 | iwts’s blog JVM内存模型中元空间所在位置 即在JVM运行时的内存模型。总体上有这样的图&#xff1a; 元空间 上面的图其实有点不太准。方法区本质上只是JVM的一个标准&#xff0c;不同JVM在不同版本下都可能有不同的实现&#x…

Matlab中函数或变量 ‘eeglab‘ 无法识别

EEGLAB 没有安装或添加到 MATLAB 路径中&#xff1a; 确保已经安装了 EEGLAB&#xff0c;并且将其添加到 MATLAB 的路径中。您可以通过在 MATLAB 命令窗口中运行 which eeglab 来检查是否能够找到 EEGLAB。 EEGLAB 函数路径设置错误&#xff1a; 如果已经安装了 EEGLAB&#x…

可以免费试用得微信辅助工具wetool升级版,可以群发,可以清理僵尸粉,可以自动回复,可以批量添加

今天给大家推荐一款我们目前在使用的电脑群发工具掘金小蜜&#xff0c;不仅可以无限多开&#xff0c;方便你同时管理多个账号&#xff0c;群发功能更是十分强大&#xff0c;轻松释放你的双手。 掘金小蜜&#xff08;只支持Win7及以上操作系统&#xff0c;没有推Mac版和手机客户…

【知识拓展】LocalTunnel-高性价比的内网穿透工具(2)

前言 上一篇通过ngrok进行内网穿透&#xff0c;有几个问题&#xff1a; ①需要注册&#xff0c;而且注册需要科学上网&#xff0c;相对麻烦 ②安装配置相对麻烦&#xff0c;authtoekn有限制 上述相对&#xff0c;指的是在非生产环境中做一个简单内网穿透&#xff0c;相对于…

neo4j开放远程连接

注&#xff1a;本博客所用neo4j版本为社区5.12版 第一步&#xff1a;修改neo4j配置文件 首先找到neo4j的安装位置&#xff0c;点击进入conf文件夹&#xff0c;随后点击neo4j.conf文件&#xff0c;在“Network connector configuration”下面的单元中找到server.default_liste…

汽车IVI中控开发入门及进阶(二十):显示技术之LCDC

TFT LCD=Thin Film Transistor Liquid Crystal Display LCDC=LCD Controller 薄膜晶体管液晶显示器(TFT LCD)控制器在驱动现代显示技术的功能和性能方面起着关键作用。它们充当屏幕后面的大脑,仔细处理数字信号,并将其转化为精确的命令,决定每个像素的行为,决定它们的…