Numpy 基础练习
1. Import Numpy
import numpy as np print(np.__version__)
1.22.1
2. 创建 Numpy 数组
2.1 使用 Numpy 内置函数创建数组
使用内置函数 np.arange() 创建一个一维数组
array = np.arange(20) print(array)
[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19]
1
查看该数组的 shape、维度 (dimension)、数据类型 (type) 及元素个数.
print("array.shape: ", array.shape) print("array.ndim: ", array.ndim) print("array.dtype: ", array.dtype) print("array.size: ", array.size)
array.shape: (20,) array.ndim: 1 array.dtype: int32 array.size: 20
使用索引访问数组中的值,注意其索引从零开始。
print(array[5])
5
与 Python 列表 (list) 不同,Numpy 数组的内容是同质(类型相同)的。 因此,如果你尝试将字符串值分配给数组中的元素(其原数据类型为 int),则会出现错误。
array[5] = "apple"
ValueError: invalid literal for int() with base 10: 'apple'
创建一个二维数组:如果只使用 np.arange() 函数,它将返回一维数组。 要使其成为二维数组,请使用 reshape 函数调整其维数。
array = np.arange(20).reshape(4,5)
[[ 0 1 2 3 4] [ 5 6 7 8 9] [10 11 12 13 14] [15 16 17 18 19]]
查看该数组的 shape、维度 (dimension)、数据类型 (type) 及元素个数
print("array.shape: ", array.shape)print("array.ndim: ", array.ndim)print("array.dtype: ", array.dtype)print("array.size: ", array.size)
array.shape: (4, 5)array.ndim: 2array.dtype: int32array.size: 20
访问二维数组中的元素,需要为行和列指定对应的索引
print(array[3])print(array[1,3])
[15 16 17 18 19]8
创建三维或跟多维度数组:和二维数组一样,如果要使用 np.arange() 函数,则需要通过 reshape 重塑数组
array = np.arange(27).reshape(3,3,3)print(array)
[[[ 0 1 2] [ 3 4 5] [ 6 7 8]] [[ 9 10 11] [12 13 14] [15 16 17]] [[18 19 20] [21 22 23] [24 25 26]]]
检查数组维度
In [17]:
print(array.shape)
(3, 3, 3)
使用 np.arange() 函数,还可以创建一个特定起始值、步长和终值的数组
array = np.arange(10,35,2.5) #起始值=10,步长=25,终值=35左闭右开print(array)print(array.dtype)
[10. 12.5 15. 17.5 20. 22.5 25. 27.5 30. 32.5]float64
使用其他内置函数创建数组:np.zeros()
print('1d:\n', np.zeros((5)))print('2d:\n', np.zeros((2,4)))print('3d:\n', np.zeros((2,4,2)))print('3d shape:\n', np.zeros((2,4,2)).shape)
1d: [0. 0. 0. 0. 0.]2d: [[0. 0. 0. 0.] [0. 0. 0. 0.]]3d: [[[0. 0.] [0. 0.] [0. 0.] [0. 0.]] [[0. 0.] [0. 0.] [0. 0.] [0. 0.]]]3d shape: (2, 4, 2)
使用其他内置函数创建数组:np.ones()
print('1d:\n', np.ones((5)))print('2d:\n', np.ones((2,2)))print('3d:\n', np.ones((2,2,4)))print('3d shape:\n', np.ones((2,2,4)).shape)
1d: [1. 1. 1. 1. 1.]2d: [[1. 1.] [1. 1.]]3d: [[[1. 1. 1. 1.] [1. 1. 1. 1.]] [[1. 1. 1. 1.] [1. 1. 1. 1.]]]3d shape: (2, 2, 4)
使用其他内置函数创建数组:full 函数创建一个填充给定值的数组。
array = np.full((2,3), 4.5)print(array)
[[4.5 4.5 4.5] [4.5 4.5 4.5]]
2.2 从Python列表 (list) 转换
除了使用 Numpy 内置函数之外,我们还可以直接从 Python 列表创建数组。将 Python 列表传递给数组函数以创建Numpy数组:
[[1 2 3] [4 5 6]]
2.3 使用特殊的库函数
要创建一个填充0到1之间随机值的数组(包含0,但不包含1),可以使用 np.random.rand() 函数。这对于需要随机状态的问题非常有用。
array = np.random.rand(2,2)print(array)
1
[[0.42684139 0.78263673] [0.45393358 0.71601223]]
np.random.randn() 函数返回一个或一组具有标准正态分布样本。
Note: 稍后我们将用到这个函数为神经网络参数进行初始化。
array = np.random.randn(2,2,4)print(array)
[[[ 0.45962594 -0.01187845 2.66755663 0.96286899] [ 0.5893254 -0.12269473 0.89063968 -3.03913871]] [[ 1.34272353 0.82122689 0.49938993 0.9271064 ] [ 0.29656562 1.37304739 -1.3572794 -1.25959598]]]
3. 一些常用的 Numpy 函数
array = np.array([[0,0,0],[1,2,3],[4,5,6]])print("argmin: ", np.argmin(array)) # 将列表展平,并给出最小值的索引print("argmax: ", np.argmax(array)) # 将列表展平,并给出最大值的索引print("mean: ", np.mean(array)) # 给出平均值print("median: ", np.median(array)) # 给出中位数
argmin: 0argmax: 8mean: 2.3333333333333335median: 2.0
print("np.maximum(array, 4):", np.maximum(array, 4)) # 我们等下将在实现 ReLU 函数时用到它print("np.minimum(array, 4):", np.minimum(array, 4))
np.maximum(array, 4): [[4 4 4] [4 4 4] [4 5 6]]np.minimum(array, 4): [[0 0 0] [1 2 3] [4 4 4]]
array = np.exp(np.array([1,2,3])) # 我们等下将在实现 Sigmoid 函数时用到它print(array)
[ 2.71828183 7.3890561 20.08553692]
array = np.log(np.array([1,2,3])) # 我们等下将在实现损失函数 (loss function / cost function) 时用到它print(array)
[0. 0.69314718 1.09861229]
4. 用 Numpy 实现矩阵运算
矩阵相加(例如:正向传播时,偏置向量与权重和激活值的运算结果相加)
array1 = np.ones((2,4))array2 = np.random.rand(2,4)print("array1: \n", array1)print("array2: \n", array2)print("array1+array2: \n", array1+array2)print("1+array2: \n", 1+array2) # 与上一行等价
array1: [[1. 1. 1. 1.] [1. 1. 1. 1.]]array2: [[0.37016269 0.51751639 0.21060369 0.37902846] [0.33209673 0.645675 0.54954808 0.0139605 ]]array1+array2: [[1.37016269 1.51751639 1.21060369 1.37902846] [1.33209673 1.645675 1.54954808 1.0139605 ]]1+array2: [[1.37016269 1.51751639 1.21060369 1.37902846] [1.33209673 1.645675 1.54954808 1.0139605 ]]
矩阵点乘,即对应元素间相乘(element-wise product)
array1 = np.arange(1,7).reshape(2,3)array2 = np.arange(1,7).reshape(2,3)print("array1: \n", array1)print("array2: \n", array2)print("array1*array2: \n", array1*array2)
矩阵乘法(例如:权重矩阵与激活向量相乘)
print("np.dot(array1,array2): \n", np.dot(array1,array2))
ValueError: shapes (2,3) and (2,3) not aligned: 3 (dim 1) != 2 (dim 0)
以上代码出现错误是因为进行矩阵乘法的两个数据大小不匹配。在相乘前,我们需要先对其中一个数组进行 reshape,以保证其大小可以进行矩阵乘法:
array2_transpose = array2.T # 返回转置矩阵,shape of array2_transpose: (3,2)print("array1: \n", array1)print("array2.T: \n", array2_transpose)print("dot product: \n", np.dot(array1,array2_transpose)) # shape of the result: (2,2)
array1: [[1 2 3] [4 5 6]]array2.T: [[1 4] [2 5] [3 6]]dot product: [[14 32] [32 77]]
以上运算还可以等价的写作:
result = array1@array2_transposeprint(result)
[[14 32] [32 77]]
矩阵对应元素间相除(例如:计算损失函数相对于网络输出的偏导)
In [34]:
print("array1: \n", array1)print("array2: \n", array2)print("array1/array2: \n", array1/array2)
array1: [[1 2 3] [4 5 6]]array2: [[1 2 3] [4 5 6]]array1/array2: [[1. 1. 1.] [1. 1. 1.]]
以上代码也可用 np.divide() 函数实现
print(np.divide(array1,array2))
[[1. 1. 1.] [1. 1. 1.]]
将矩阵元素沿某个维度相加
print("array1: \n", array1)print("array1.sum(axis=0): \n", array1.sum(axis=0))print("array1.sum(axis=1): \n", array1.sum(axis=1))print("array1.sum(): \n", array1.sum())
array1: [[1 2 3] [4 5 6]]array1.sum(axis=0): [5 7 9]array1.sum(axis=1): [ 6 15]array1.sum(): 21