Featured image of post 深度学习系列-NumPy核心及重难点

深度学习系列-NumPy核心及重难点

NumPy是一个功能强大的Python库,主要用于对多维数组执行计算。

深度学习系列 NumPy核心及重难点

NumPy是一个功能强大的Python库,主要用于对多维数组执行计算。NumPy这个词来源于两个单词– NumericalPython。NumPy提供了大量的库函数和操作,可以帮助程序员轻松地进行数值计算。这类数值计算广泛用于以下任务:

  • 机器学习模型:在编写机器学习算法时,需要对矩阵进行各种数值计算。例如矩阵乘法、换位、加法等。NumPy提供了一个非常好的库,用于简单(在编写代码方面)和快速(在速度方面)计算。NumPy数组用于存储训练数据和机器学习模型的参数。
  • 图像处理和计算机图形学:计算机中的图像表示为多维数字数组。NumPy成为同样情况下最自然的选择。实际上,NumPy提供了一些优秀的库函数来快速处理图像。例如,镜像图像、按特定角度旋转图像等。
  • 数学任务:NumPy对于执行各种数学任务非常有用,如数值积分、微分、内插、外推等。因此,当涉及到数学任务时,它形成了一种基于Python的MATLAB的快速替代。

NumPy的基本操作代码如下所示:

import numpy as np
a = np.array([[1.0, 2.0], [3.0, 4.0]])
b = np.array([[5.0, 6.0], [7.0, 8.0]])
c = np.zeros((2,2)) # 创建两行两列的全0矩阵
d = np.ones((1,2)) # 创建1行两列的全1矩阵
e = np.full((2,2), 7) # 创建两行两列的全为7的矩阵
f = np.eye(2) # 创建2x2识别数组
g = np.random.random((2,2)) # 创建两行两列随机数组
sum = a + b
difference = a - b
product = a * b
matrix_product = a.dot(b)
quotient = a / b
square = a ** 2
print(f"Sum = {sum}, Difference = {difference}, Product = {product}, Quotient = {quotient}, MatrixProduct = {matrix_product}, Square = {square}")
print(a.sum(), a.min(), a.max()) # 结果:10.0 1.0 4.0
print(type(a)) # a 的类型为ndarray 结果:<class 'numpy.ndarray'>
print(a.dtype) # a 的数据类型为float64 结果:float64
print(a.size)  # a 中的数据元素共多少个 结果:4
print(a.shape) # a 数据的形状 结果:(2, 2)
print(a.itemsize) # itemsize属性是每个项占用的字节数。这个数组的数据类型是int64,一个int64中有64位,一个字节中有8位,除以64除以8,可以得到占用的字节数 结果:8
print(a.ndim) # a 的数组的维数 结果:2
print(a.nbytes) # nbytes 属性是数组中的所有数据消耗掉的字节数。 结果:32
# 结果如下:
Sum = [[ 6. 8.] [10. 12.]]
Difference = [[-4. -4.] [-4. -4.]]
Product = [[ 5. 12.] [21. 32.]]
Quotient = [[0.2 0.33333333] [0.42857143 0.5 ]]
MatrixProduct = [[19. 22.] [43. 50.]]
Square = [[ 1.  4.] [ 9. 16.]]

NumPy中的数组可以直接进行加减乘除的操作,对于两个ndarray数组直接进行乘法操作是执行逐元素乘法而不是矩阵乘法。矩阵乘法可使用dot函数实现。

矢量是具有方向和幅度的量。它们通常用于表示速度,加速度和动量等事物。向量可以用多种方式编写,在NumPy中记为n元组的形式。矩阵类似于矢量由行和列组成,类似于网格。

多维数组切片

多维数组切片示例

如上图所示,共五种情况:

  • 若访问数组中的一个元素时,[1,2]表示数组中的第2行,第3列(行列起始坐标均为0)。

  • 若访问数组中的一行元素时,[1,:]表示数组中的第2行开始,列数值为空时表示取第2行的所有值。

  • 若访问数组中的一列元素时,此时行数值为空,列数值表示取第2列的所有值。

  • 若要对目标数组的区域切片时,如[1:3,1:],表示取该数组的第2行到第3行,第四行为开区间,故第四行不取。列数值自第2列起始,:后为空为取该数组的第2列至最后一列。

  • 若需要对目标数组的区域取跳跃切片时,可使用[::3,::2]的方法表示,::3表示从第0行开始取,下一次的取值为2行之后,即每3行取一次数值,::2同理可得从第0列开始取,下一次的取值为1列之后,即每2列取一次数值。

cumsum()函数详解

import numpy as np
a = [1, 2, 3, 4, 5, 6, 7]
print(np.cumsum(a)) # Tag 1
b = [[1,2,3], [4,5,6], [7,8,9]]
print(np.cumsum(b, axis=0)) # Tag2
print(np.cumsum(b, axis=1)) # Tag3
c = [[[1,2,3], [4, 5, 6]], [[7,8,9], [10,20,30]]]
print(np.cumsum(c, axis=0)) # Tag4
print(np.cumsum(c, axis=1)) # Tag5
print(np.cumsum(c, axis=2)) # Tag6

运行上面的代码标记处1可得结果array([1,3,6,10,15,21,28]),解法为取a中的第一个元素为标记结果的第一个元素,第二个元素为取第一个元素与第二个元素之和,即1+2=3,第三个元素为上一次计算的结果与下一个元素之和,即3+3=6,第四个元素为上一次计算的结果与下一个元素之和,即6+4=10,之后的结果同理可得。

运行上面的代码标记处2可得结果array([[1,2,3], [5,7,9], [12,15,18]]),当参数axis=0时,取b中的第一个元素为标记结果的第一个元素,第二个元素为第一个元素与第二个元素的对应之和相加,即[1,2,3]+[4,5,6] = [5,7,9]。第三个元素为第二个元素与第三个元素之和叠加,即[5,7,9]+[7,8,9] = [12,15,18]。总结:当axis=0时,其规律为第1行不动,将第1行累加到其他行。

运行上面的代码标记处3可得结果array([[1,3,6], [4,9,15], [7, 15, 24]]), 当参数axis=1时,第一个元素[1,2,3]中的首位不变,次位变更为首位元素加上本位元素即1+2=3,末位元素为次位元素与本位元素的和,即3+3=6。第二个元素[4,5,6]中的首位仍不变,次位变更为首位元素加上本位元素即4+5=9。末位元素为次位元素与本位元素的和,即9+6=15。第三个元素同理。总结:当axis=1时,数组元素转为列处理。第一列不动,将第1列累加到其他列。

运行上面的代码标记处4可得结果array([[[1, 2, 3], [4, 5, 6]], [[8, 10, 12], [14, 25, 36]]])),当参数axis=0时,最外面一层中,共有2个元素。第一个元素不动,累加至第二行。即[[1,2,3], [4, 5, 6]]+[[7,8,9], [10,20,30]]=[[[1,2,3], [4,5,6]], [[8, 10, 12], [14,25,36]]]。即第二个元素执行的操作为1+7,2+8,3+9,4+10,5+20,6+30。

运行上面的代码标记处5可得结果array([[[1, 2, 3], [5, 7, 9]],[[7, 8, 9], [17, 28, 39]]])),当参数axis=1时,最外一层有两个元素,进入元素中,第一个子元素为[1,2,3]和[4,5,6],第二个子元素为[7,8,9]和[10,20,30]。此时的叠加操作与二维数组中axis=0时类似,第一个子元素的[1,2,3]不动,对[4,5,6]叠加后是[5,7,9]。第二个子元素同理可得对子元素的第二部分叠加后为[17,28,39]。(7+10,8+20,9+30)。

运行上面的代码标记处6可得结果array([[[1, 3, 6], [4, 9, 15]],[[7, 15, 24], [10, 30, 60]]])),当参数axis=2时,最外一层有两个元素,进入元素中,第一个子元素为[1,2,3]和[4,5,6],第二个子元素为[7,8,9]和[10,20,30]。此时的叠加操作与二维数组中axis=1时类似,数组元素转为列处理。处在第一列的1,4不动,第二列的值2和5执行叠加操作1+2和4+5得结果3与9。第三列的值3和6执行叠加操作3+3和9+6得结果6与15。第二个子元素同理可得。

总结:一维数组逐个叠加。二维数组axis=0按行叠加,axis=1按列叠加。三维数组axis=0按元素叠加,axis=1按行叠加,axis=2按列叠加。

本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可。