2025-03-15 Python深度学习2——Numpy库

embedded/2025/3/17 0:20:10/

文章目录

  • 1 基础
    • 1.1 数据类型
      • 1.1.1 整型数组与浮点型数组
      • 1.1.2 元素同化
      • 1.1.3 数组类型转换
    • 1.2 数组维度
      • 1.2.1 一维数组与二维数组
      • 1.2.2 数组形状变换
  • 2 创建数组
    • 2.1 创建指定数组
    • 2.2 创建递增数组
    • 2.3 创建同值数组
    • 2.4 创建随机数组
  • 3 索引
    • 3.1 访问数组元素
      • 3.1.1 访问向量
      • 3.1.2 访问矩阵
    • 3.2 花式索引
      • 3.2.1 向量花式索引
      • 3.2.2 矩阵花式索引
    • 3.3 数组切片
      • 3.3.1 向量切片
      • 3.3.2 矩阵切片
      • 3.3.3 提取矩阵行
      • 3.3.4 提取矩阵列
    • 3.4 切片是视图!!!
      • 3.4.1 切片是视图
      • 3.4.2 拷贝切片
    • 3.5 数组赋值是绑定
      • 3.5.1 数组赋值是绑定
      • 3.5.2 拷贝数组
  • 4 数组的变形
    • 4.1 数组转置
      • 4.1.1 向量转置
      • 4.1.2 矩阵转置
    • 4.2 数组翻转
      • 4.2.1 向量翻转
      • 4.2.2 矩阵翻转
    • 4.3 数组变形
      • 4.3.1 向量变形
      • 4.3.2 矩阵变形
    • 4.4 数组拼接
      • 4.4.1 向量拼接
      • 4.4.2 矩阵拼接
    • 4.5 数组拆分
      • 4.5.1 向量拆分
      • 4.5.2 矩阵拆分
  • 5 运算
    • 5.1 数组与标量运算
    • 5.2 数组与数组运算
    • 5.3 广播
      • 5.3.1 向量广播
      • 5.3.2 列矩阵广播
      • 5.3.3 矩阵同时广播
  • 6 数组函数
    • 6.1 矩阵乘积
      • 6.1.1 向量与向量
      • 6.1.2 向量与矩阵
      • 6.1.3 矩阵与向量
      • 6.1.4 矩阵与矩阵
    • 6.2 数学函数
    • 6.3 聚合函数
  • 7 布尔型数组
    • 7.1 创建
    • 7.2 布尔型数组中 True 的数量
    • 7.3 布尔型数组作为掩码
    • 7.4 满足条件的元素所在位置
  • 8 数组与张量

本文使用的 Python 解释器与 NumPy 库的版本如下。

  • Python 3.12.9
  • NumPy 2.1.2

1 基础

1.1 数据类型

1.1.1 整型数组与浮点型数组

​ 为克服 Python 内置列表的缺点,一个 NumPy 数组只有 1 种数据类型,以节约内存。

image-20250315095018545

​ 注意,使用 print 输出 NumPy 数组后,元素之间没有逗号。一来可以与 Python 内置列表区分,二来可以避免逗号与小数点之间的混淆。

1.1.2 元素同化

  • 往整数型数组里插入浮点数,该浮点数会被自动截断为整数;
  • 往浮点型数组里插入整数,该整数会被自动升级为浮点数。
image-20250315095150137

1.1.3 数组类型转换

​ 整数型数组和浮点型数组之间的界限十分严格,要将整数型数组和浮点型数组相互转换,规范的方法是使用 .astype() 方法。

image-20250315095221734

​ 此外,整数型数组在运算过程中也可升级为浮点型数组,示例如下。

image-20250315095240339

​ 整数型数组很好升级,但浮点型数组在运算过程中一般不会降级。

1.2 数组维度

1.2.1 一维数组与二维数组

深度学习三维及其以上的数组出现次数少,我们后续主要讲解。

​ NumPy 中的一维数组和二维数组,学了一维和二维后,很好类推到三维。

  1. 不同维度的数组之间,从外形上的本质区别是
    • 一维数组使用1层中括号表示;
    • 二维数组使用2层中括号表示;
    • 三维数组使用3层中括号表示。
  2. 有些函数需要传入数组的形状参数,不同维度数组的形状参数为
    • 一维数组的形状参数形如: x 或 (x,) ;
    • 二维数组的形状参数形如: (x, y) ;
    • 三维数组的形状参数形如: (x, y, z) 。
  3. 现在以同一个序列进行举例
    • 当数组有 1 层中括号,如 [1 2 3],则其为一维数组,其形状是 3 或 (3, ) ;
    • 当数组有 2 层中括号,如 [[1 2 3]],则其为二维数组,其形状是 (1, 3) ;
    • 当数组有 3 层中括号,如 [[[1 2 3]]],则其为三维数组,其形状是 (1, 1, 3) ;
image-20250315095317576

​ 可以使用数组 .shape 属性查看 arr1 和 arr2 的形状。

image-20250315095336683

1.2.2 数组形状变换

​ 一维数组转二维数组,还是二维数组转一维数组,均要使用的是数组的重塑方法 .reshape() ,该方法需要传入重塑后的形状(shape)参数。

​ 这个方法神奇的是,给定了其他维度的数值,剩下一个维度可以填 -1,让它自己去计算。
​ 例如,把一个 5 行 6 列的矩阵重塑为 3 行 10 列的矩阵,当列的参数 10 告诉它,行的参数直接可以用 -1 来替代,它会自己去用 30 除以 10 来计算。

image-20250315095404920

​ 这里演示给 .reshape() 传入的形状参数是 (1, -1),正常情况下一般传入 (1, 10)。

​ (1, -1) 的含义是:行的参数是 1 行,列的参数 -1 让 NumPy 自己去除着算。

image-20250315095459137

​ 规定,将一维数组称为向量,二维数组称为矩阵。

2 创建数组

2.1 创建指定数组

​ 当明确知道数组每一个元素的具体数值时,可以使用 np.array() 函数,将 Python 列表转化为 NumPy 数组。

image-20250315095536755

2.2 创建递增数组

​ 递增数组使用 np.arange() 函数进行创建(arange 全称是 array_range)。

image-20250315095609830

2.3 创建同值数组

​ 创建同值数组时,使用 np.zeros() 函数以及 np.ones() 函数,如示例。

image-20250315095658788

​ 示例中隐藏了一个细节——两个函数输出的并不是整数型的数组,这可能是为了避免插进去的浮点数被截断,所以将其设定为浮点型数组。

2.4 创建随机数组

​ 创建随机数组,可以使用 np.random 系列函数,如示例所示。

image-20250315095739101

3 索引

3.1 访问数组元素

​ 与 Python 列表一致,访问 NumPy 数组元素时使用中括号,索引由 0 开始。

3.1.1 访问向量

image-20250315095813959

3.1.2 访问矩阵

image-20250315095925554

3.2 花式索引

​ 花式索引(Fancy indexing)又名“花哨的索引”,这里的 Fancy 应取“华丽的、巧妙的、奢华的、时髦的”之义。

​ 上一小节访问单个元素时,向量用 arr1[x],矩阵用 arr2[x,y]。逗号在矩阵里用于区分行与列。

​ 这一小节,逗号新增一个功能,且不会与矩阵里的逗号混淆。

普通索引用一层中括号,花式索引用两层中括号。

3.2.1 向量花式索引

image-20250315100002444

3.2.2 矩阵花式索引

image-20250315100027459

​ 根据以上实例,花式索引输出的仍然是一个向量。

image-20250315104542005

3.3 数组切片

3.3.1 向量切片

​ 向量与列表切片的操作完全一致。

image-20250315104000840 image-20250315100142046

3.3.2 矩阵切片

image-20250315100201706

3.3.3 提取矩阵行

​ 基于矩阵切片功能,可以提取其部分行。

image-20250315100225211

​ 所以,有时你可能看到诸如 arr[1][2] 这样的语法,这是先提取了第 1 行,再提取该行中第 2 个元素。
​ 这种写法不是推荐。

3.3.4 提取矩阵列

image-20250315100311891

​ 提取某一个单独的列时,出来的结果是一个向量。这么做是为了省空间,因为列矩阵必须用两层中括号来存储。

​ 形状为 1000 的向量,自然比形状为 (1000, 1) 的列矩阵更省空间(节约了 1000 对括号)。

​ 如果想要提取一个列矩阵出来,示例如下。

image-20250315100410727

3.4 切片是视图!!!

3.4.1 切片是视图

​ 与 Python 列表和 Matlab 不同,NumPy 数组的切片仅仅是原数组的一个视图。

​ 换言之,NumPy 切片并不会创建新的变量,示例如下。

image-20250315100443834

​ 习惯 Matlab 的用户可能无法理解,但其实这正是 NumPy 的精妙之处。

​ 试想一个几百万条数据的数组,每次切片时都创建一个新变量,势必造成大量内存浪费。

​ 因此,NumPy 的切片被设计为原数组的视图是极好的。

深度学习中为节省内存,将多次使用 arr[:] = <表达式> 来替代 arr = <表达式>。

3.4.2 拷贝切片

image-20250315100510520

3.5 数组赋值是绑定

3.5.1 数组赋值是绑定

​ 与 NumPy 数组的切片一样,NumPy 数组完整的赋值给另一个数组,也只是绑定。

​ 换言之,NumPy 数组之间的赋值并不会创建新的变量,示例如下。

image-20250315100535330

3.5.2 拷贝数组

​ 如果真的需要赋给一个新数组,使用 .copy() 方法。

image-20250315100554971

4 数组的变形

4.1 数组转置

​ 数组的转置方法为 .T,其只对矩阵有效,因此遇到向量要先将其转化为矩阵。

4.1.1 向量转置

image-20250315100627468

4.1.2 矩阵转置

​ 行矩阵(向量)的转置刚演示了,列矩阵的转置如示例所示。

image-20250315100652014

4.2 数组翻转

​ 数组的翻转方法有两个,一个是上下翻转的 np.flipud() ,表示 up-down;

​ 一个是左右翻转的 np.fliplr(),表示 left-right。

​ 其中,向量只能使用 np.flipud()。在数学中,向量并不是横着排的,而是竖着排的。

4.2.1 向量翻转

image-20250315100721088

4.2.2 矩阵翻转

image-20250315100747192

4.3 数组变形

​ 想要重塑数组的形状,需要用到 .reshape() 方法。

​ 前面说过,把一个 5 行 6 列的矩阵重塑为 3 行 10 列的矩阵,当列的参数 10 告诉它,行的参数直接可以用 -1 来替代,它会自己去用 30 除以 10 来计算。

4.3.1 向量变形

image-20250315100816359

4.3.2 矩阵变形

image-20250315100836478

4.4 数组拼接

4.4.1 向量拼接

​ 两个向量拼接,将得到一个新的加长版向量。

image-20250315100858840

4.4.2 矩阵拼接

​ 两个矩阵可以按不同的维度进行拼接,但拼接时必须注意维度的吻合。

image-20250315100955502

​ 最后要说明的是,向量和矩阵不能进行拼接,必须先把向量升级为矩阵。

4.5 数组拆分

4.5.1 向量拆分

​ 向量分裂,将得到若干个更短的向量。

image-20250315101036766

​ np.split() 函数中,给出的第二个参数 [2,8] 表示在索引 [2] 和索引 [8] 的位置截断。

4.5.2 矩阵拆分

​ 矩阵的分裂同样可以按不同的维度进行,分裂出来的均为矩阵。

image-20250315101105437

5 运算

5.1 数组与标量运算

​ Python 基础中,常用的运算符如表 5-1 所示,NumPy 的运算符与之相同。

image-20250315104506707 image-20250315101146686 image-20250315101207757

5.2 数组与数组运算

​ 同维度数组间的运算即对应元素之间的运算,这里仅以矩阵为例,向量与向量的操作与之相同。

image-20250315101251455

​ 乘法是遵循对应元素相乘的,你可以称之为“逐元素乘积”。

​ 如何实现线性代数中的“矩阵级乘法”呢?6.1 会介绍到相关函数。

5.3 广播

​ 不同形状的数组之间的运算有以下规则:

  • 如果是向量与矩阵之间做运算,向量自动升级为行矩阵;
  • 如果某矩阵是行矩阵或列矩阵,则其被广播,以适配另一个矩阵的形状。

5.3.1 向量广播

​ 当一个形状为 (x, y) 的矩阵与一个向量做运算时,要求该向量的形状必须为 y,运算时向量会自动升级成形状为 (1, y) 的行矩阵,该形状为 (1, y) 的行矩阵再自动被广播为形状为 (x, y) 的矩阵,这样就与另一个矩阵的形状适配了。

image-20250315101337525

5.3.2 列矩阵广播

​ 当一个形状为 (x, y) 的矩阵与一个列矩阵做运算时,要求该列矩阵的形状必须为 (x, 1),该形状为 (x, 1) 的列矩阵再自动被广播为形状为 (x, y) 的矩阵,这样就与另一个矩阵的形状适配了。

image-20250315101400016

5.3.3 矩阵同时广播

​ 当一个形状为 (1, y) 的行矩阵与一个形状为 (x, 1) 的列矩阵做运算时,这俩矩阵都会被自动广播为形状为 (x, y) 的矩阵,这样就互相适配了。

image-20250315101425274

6 数组函数

6.1 矩阵乘积

  • 第五章中的乘法都是“逐元素相乘”,这里介绍线性代数中的矩阵乘积,本节只需要使用 np.dot() 函数。
  • 当矩阵乘积中混有向量时,根据需求,其可充当行矩阵,也可充当列矩阵,但混有向量时输出结果必为向量。

6.1.1 向量与向量

​ 设两个向量的形状按前后顺序分别是 5 以及 5 。从矩阵乘法的角度,有 (1, 5) * (5, 1) = (1, 1),因此输出的应该是形状为 1 的向量。

image-20250315101453166

6.1.2 向量与矩阵

​ 设向量的形状是 5,矩阵的形状是 (5, 3)。从矩阵乘法的角度,有 (1, 5) * (5, 3) = (1, 3),因此输出的应该是形状为 3 的向量。

image-20250315101517521

6.1.3 矩阵与向量

​ 设矩阵的形状是 (3, 5),向量的形状是 5。从矩阵乘法的角度,有 (3, 5) * (5, 1) = (3, 1),因此输出的应该是形状为 3 的向量。

image-20250315101541307

6.1.4 矩阵与矩阵

​ 设矩阵的形状是 (5, 2) 以及 (2, 8)。从矩阵乘法的角度,有 (5, 2) * (2, 8) = (5, 8),因此输出的应该是形状为 (5, 8) 的矩阵。

image-20250315101615188

6.2 数学函数

​ NumPy 设计了很多数学函数,这里列举其中最重要、最常见的几个。

image-20250315101649811 image-20250315101706905

6.3 聚合函数

​ 聚合很有用,这里用矩阵演示。向量与之一致,但没有 axis 参数。以下在注释中介绍了 6 个最重要的聚合函数,其用法完全一致,仅演示其中 3 个。

image-20250315101828301
  • 当 axis=0 时,最终结果与每一行的元素个数一致;
  • 当 axis=1 时,最终结果与每一列的元素个数一致。

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

7 布尔型数组

​ 除了整数型数组和浮点型数组,还有一种有用的数组类型——布尔型数组。

7.1 创建

​ 由于 NumPy 的主要数据类型是整数型数组或浮点型数组,因此布尔型数组的产生离不开:大于 >、大于等于 >=、等于 ==、不等号 !=、小于 <、小于等于 <=。

​ 首先,我们将数组与系数作比较,以产生布尔型数组,示例如下。

image-20250315101933512

​ 其次,我们将同维数组作比较,以产生布尔型数组,示例如下。

image-20250315101953206

​ 最后,还可以同时比较多个条件。Python 里同时检查多个条件使用的与、或、非是 and、or、not。但 NumPy 中使用的与、或、非是 & 、 | 、 ~ 。

image-20250315102018269

7.2 布尔型数组中 True 的数量

​ 有三个关于 True 数量的有用函数,分别是 np.sum()、np.any()、np.all()。

​ np.sum() 数:统计布尔型数组里 True 的个数。示例如下。

image-20250315102238257

​ 从结果来看,arr1 与 arr2 里含有共同元素,那就是 5。

​ np.all() 函数:当布尔型数组里全是 True 时,才返回 True,示例如下。

image-20250315102353382

​ 从结果来看,尽管 3σ 准则告诉我们有 99.73% 的考生成绩高于 290 分,但仍然有最终成绩低于 250 分的裸考者。

7.3 布尔型数组作为掩码

​ 若一个普通数组和一个布尔型数组的维度相同,可以将布尔型数组作为普通数组的掩码,这样可以对普通数组中的元素作筛选。给出两个示例。

​ 第一个示例,筛选出数组中大于、等于或小于某个数字的元素。

image-20250315102506075

​ 注意,这个矩阵进行掩码操作后,退化为了向量。

​ 第二个示例,筛选出数组逐元素比较的结果。

image-20250315102547283

7.4 满足条件的元素所在位置

​ 现在我们来思考一种情况:假设一个很长的数组,我想知道满足某个条件的元素们所在的索引位置,此时使用 np.where() 函数。

image-20250315102609992

​ np.where() 函数的输出看起来比较怪异,它是输出了一个元组。

​ 元组第一个元素是“满足条件的元素所在位置”;第二个元素是数组类型,可忽略掉。

8 数组与张量

​ PyTorch 作为当前首屈一指的深度学习库,其将 NumPy 的语法尽数吸收,作为自己处理数组的基本语法,且运算速度从使用 CPU 的数组进步到使用 GPU 的张量。

​ NumPy 和 PyTorch 的基础语法几乎一致,具体表现为:

  1. np 对应 torch;
  2. 数组 array 对应张量 tensor;
  3. NumPy 的 n 维数组对应着 PyTorch 的 n 阶张量。

​ 数组与张量之间可以相互转换:

  1. 数组 arr 转为张量 ts:ts = torch.tensor(arr);
  2. 张量 ts 转为数组 arr:arr = np.array(ts)。
NumPy函数PyTorch函数区别
.astype().type()
np.random.random()torch.rand()
np.random.randint()torch.randint()不接纳一维张量
np.random.normal()torch.normal()不接纳一维张量
np.random.randn()torch.randn()
.copy().clone()
np.concatenate()torch.cat()
np.split()torch.split()参数含义优化
np.dot()torch.matmul()
np.dot(v,v)torch.dot()
np.dot(m,v)torch.mv()
np.dot(m,m)torch.mm()
np.exp()torch.exp()必须传入张量
np.log()torch.log()必须传入张量
np.mean()torch.mean()必须传入浮点型张量
np.std()torch.std()必须传入浮点型张量

http://www.ppmy.cn/embedded/173193.html

相关文章

SOME/IP-SD -- 协议英文原文讲解8

前言 SOME/IP协议越来越多的用于汽车电子行业中&#xff0c;关于协议详细完全的中文资料却没有&#xff0c;所以我将结合工作经验并对照英文原版协议做一系列的文章。基本分三大块&#xff1a; 1. SOME/IP协议讲解 2. SOME/IP-SD协议讲解 3. python/C举例调试讲解 5.1.4.4 S…

《灵珠觉醒:从零到算法金仙的C++修炼》卷三·天劫试炼(40)翻天印压回文串 - 最长回文子序列(区间DP)

《灵珠觉醒:从零到算法金仙的C++修炼》卷三天劫试炼(40)翻天印压回文串 - 最长回文子序列(区间DP) 哪吒在数据修仙界中继续他的修炼之旅。这一次,他来到了一片神秘的回文森林,森林中有一本古老的翻天印,印身闪烁着神秘的光芒。森林的入口处有一块巨大的石碑,上面刻着…

作业9 (2023-05-05 数组的定义和初始化)

第1题/共11题【单选题】 关于一维数组初始化,下面哪个定义是错误的?( ) A.int arr[10] = {1,2,3,4,5,6}; B.int arr[] = {1,2,3,4,5,6}; C.int arr[] = (1,2,3,4,5,6); D.int arr[10] = {0}; A:正确,10个int的一段连续空间,前6个位置被初始化为1,2,3,4,5,6,其他…

《基于机器学习(xgboost)的人体卡路里消耗预测系统》开题报告

目录 1 选题的背景和意义 1.1 选题的背景 1.2 国内外研究现状及发展趋势 2 研究的基本内容 2.1 基本框架 2.1.1数据输入模块 2.1.2数据预处理模块 2.1.3特征工程模块 2.1.4模型训练与评估模块 2.1.5预测与输出模块 2.1.6用户界面(UI) 2.1.7系统维护与更新模块 2.…

MATLAB中envelope函数使用

目录 说明 示例 chirp 的解析包络 使用滤波器计算多通道信号的解析包络 录音信号的移动 RMS 包络 语音信号的峰值包络 不对称序列的包络 envelope函数的功能是提取信号的包络。 语法 [yupper,ylower] envelope(x) [yupper,ylower] envelope(x,fl,analytic) [yupper,…

STM32驱动代码规范化编写指南(嵌入式C语言方向)

点击下面图片&#xff0c;为您提供全新的嵌入式学习路线 文章目录 一、命名规范体系1.1 变量/函数命名1.2 宏定义规范1.3 类型定义 二、代码结构组织2.1 文件组织结构2.2 头文件规范模板 三、注释体系构建3.1 Doxygen风格示例3.2 复杂逻辑注释 四、硬件抽象层设计4.1 寄存器封…

探索HTML5 Canvas:创造动态与交互性网页内容的强大工具

探索HTML5 Canvas&#xff1a;创造动态与交互性网页内容的强大工具 引言 在HTML5的众多新特性中&#xff0c;Canvas无疑是最引人注目的元素之一。它为网页设计师和开发者提供了一个通过JavaScript和HTML直接在网页上绘制图形、图像以及进行动画处理的画布。Canvas的灵活性和强…

【Node.js】--- win11安装 Node.js

在编程的艺术世界里,代码和灵感需要寻找到最佳的交融点,才能打造出令人为之惊叹的作品。而在这座秋知叶i博客的殿堂里,我们将共同追寻这种完美结合,为未来的世界留下属于我们的独特印记。【Node.js】--- win11安装 Node.js 开发环境一、Node.js简介二、安装Node.js1、设置向…