Numpy与线性代数(Linear Algebra)
Numpy是基于python的一个常用库,利用它来方便地操纵数组。
在python中使用numpy这个库需要提前导入,并起个别名为np
:
1 | import numpy as np |
1 numpy数组与python列表
定义python列表: 1
alist = [1, 2, 3, 4]
1
narray = np.array([1, 2, 3, 4])
1
2
3
4
5print('alist:', alist)
print('narray:', narray)
print('Type of alist:', type(alist))
print('Type of narray:', type(narray))[1, 2, 3, 4]
[1 2 3 4]
<class 'list'>
<class 'numpy.ndarray'>
2 numpy数组与python列表的运算符
numpy数组与python列表的+
和*
含义不同,其中numpy数组是真正在进行代数运算。
+
的不同: 1
print(narray + narray)
[2 4 6 8]
1 | print(alist + alist) |
[1, 2, 3, 4, 1, 2, 3, 4]
*
的不同: 1
print(narray * 3)
[ 3 6 9 12]
1 | print(alist * 3) |
[1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]
3 矩阵(Matrix)
在线性代数中,矩阵是指一种由n行m列的结构,它是一个矩形,所以每一行都有相同的列数。利用numpy创建矩阵:
numpy可以用数组(array)或者列表来初始化一个矩阵,但最后都是数组(array)的类型。 1
2
3matrix1 = np.array([narray, narray, narray])
matrix2 = np.array([alist, alist, alist])
matrix3 = np.array([narray, [1, 1, 1, 1], narray])1
2
3print('matrix1:', matrix1)
print('matrix2:', matrix2)
print('matrix3', matrix3)1
2
3
4
5
6
7
8
9
10
11
12matrix1:
[[1 2 3 4]
[1 2 3 4]
[1 2 3 4]]
matrix2:
[[1 2 3 4]
[1 2 3 4]
[1 2 3 4]]
matrix3:
[[1 2 3 4]
[1 1 1 1]
[1 2 3 4]]1
2
3badmatrix = np.array([[1, 2], [3, 4], [5, 6, 7]]) # Define a matrix. Note the third row contains 3 elements
print(badmatrix) # Print the malformed matrix
print(badmatrix * 2) # It is supposed to scale the whole matrixz[list([1, 2]) list([3, 4]) list([5, 6, 7])]
[list([1, 2, 1, 2]) list([3, 4, 3, 4]) list([5, 6, 7, 5, 6, 7])]
3.1 矩阵的四则运算
定义一个矩阵: 1
okmatrix = np.array([[1, 2], [3, 4]])
矩阵进行加减时要逐渐两个矩阵是拥有相同结构的,即行和列数要对应相同。 1
2
3
4
5resutlt1 = okmatrix + okmatrix
result2 = okmatrix - okmatrix
print(result1)
print(result2)1
2
3
4
5[[2 4]
[6 8]]
[[0 0]
[0 0]]
1 | result = okmatrix * 2 |
1 | [[2 4] |
假如是矩阵和矩阵相乘,它是基于元素进行相乘,每个元素和对应位置的元素相乘。矩阵乘法要和点积(dot product)区分。 1
2result = okmatrix * okmatrix # Multiply each element by itself
print(result)1
2[[ 1 4]
[ 9 16]]
1 | result = okmatrix / okmatrix |
1 | [[1. 1.] |
3.2 矩阵的转置
矩阵的转置是指将矩阵沿着对角线进行翻转,行变成列。如果转置前的矩阵是n*m
,那么转置后的矩阵是m*n
。T代表numpy矩阵的转置操作。 1
2
3
4
5matrix = np.array([[1, 2], [3, 4], [5, 6]]) # Define a 3x2 matrix
print('Original matrix 3 x 2')
print(matrix)
print('Transposed matrix 2 x 3')
print(matrix.T)1
2
3
4
5
6
7Original matrix 3 x 2
[[1 2]
[3 4]
[5 6]]
Transposed matrix 2 x 3
[[1 3 5]
[2 4 6]]1
2
3
4
5nparray = np.array([1, 2, 3, 4]) # Define an array
print('Original array')
print(nparray)
print('Transposed array')
print(nparray.T)1
2
3
4Original array
[1 2 3 4]
Transposed array
[1 2 3 4]1
2
3
4
5narray = np.array([[1, 2, 3, 4]])
print('Original array')
print(nparray)
print('Transposed array')
print(nparray.T)1
2
3
4
5
6
7Original array
[[1 2 3 4]]
Transposed array
[[1]
[2]
[3]
[4]]
此处为2-范数。
向量的2-范数描述向量在空间中的大小(距离)。向量范数的本质是距离,存在的意义是为了实现比较。比如,在一维实数集合中,我们随便取两个点4和9,我们知道9比4大,但是到了二维实数空间中,取两个点(1,1)和(0,3),这个时候我们就没办法比较它们之间的大小,因为它们不是可以比较的实数,于是我们引入范数这个概念,把我们的(1,1)和(0,3)通过范数分别映射到实数\(\sqrt{2}\) 和 3 ,这样我们就比较这两个点了。对于向量\(x = (x_1;x_2; ...; x_n)\),它的Norm为 \[ ||x|| = \sqrt{x^T x} = (\sum_{i=1}^n x_i^2)^{\frac 12} = \sqrt{x_1^2 +x_2^2 + ...+x_n^2} \]
矩阵的对于m*n
的矩阵\(A\)来说,Norm为: \[
||A|| = \sqrt{\sum_{ij}{|a_{ij}|}^2}
\]
利用numpy下的子包linalg中的norm
函数可以进行计算。 1
2
3
4
5
6
7
8nparray1 = np.array([1, 2, 3, 4])
norm1 = np.linalg.norm(nparray1)
nparray2 = np.array([[1, 2], [3, 4]])
norm2 = np.linalg.norm(nparray2)
print(norm1)
print(norm2)1
25.477225575051661
5.477225575051661norm
函数中的参数axis
来计算每行或者每列的范数。 * axis=0 得到每列的范数。 * axis=1 得到每行的范数。 1
2
3
4
5
6
7
8
9
10nparray2 = np.array([[1, 1], [2, 2], [3, 3]]) # Define a 3 x 2 matrix.
print('nparray2:')
print(nparray2)
normByCols = np.linalg.norm(nparray2, axis=0)
normByRows = np.linalg.norm(nparray2, axis=1)
print('normByCols')
print(normByCols)
print('normByRows')
print(normByRows)1
2
3
4
5
6
7
8nparray2:
[[1 1]
[2 2]
[3 3]]
normByCols
[3.74165739 3.74165739]
normByRows
[1.41421356 2.82842712 4.24264069]
向量的点积: 1
2
3
4
5nparray1 = np.array([0, 1, 2, 3]) # Define an array
nparray2 = np.array([4, 5, 6, 7]) # Define an array
result = np.dot(nparray1, nparray2)
print(result)38
6 按行或按列求和
numpy中的sum
函数可以进行求和,通过设置axis
实现行(1)或列(0)的求和。 1
2
3
4
5
6
7
8
9
10
11nparray2 = np.array([[1, -1], [2, -2], [3, -3]]) # Define a 3 x 2 matrix.
print(nparray2)
sumByCols = np.sum(nparray2, axis=0)
sunByRows = np.sum(nparray2, axis=1)
print('Sum by columns: ')
print(sumByCols)
print('Sum by rows:')
print(sumByRows)1
2
3
4
5
6
7[[ 1 -1]
[ 2 -2]
[ 3 -3]]
Sum by columns:
[ 6 -6]
Sum by rows:
[0 0 0]
利用np.mean()
或者array.mean()
。 1
2
3
4
5
6
7
8
9
10
11
12nparray2 = np.array([[1, -1], [2, -2], [3, -3]]) # Define a 3 x 2 matrix. Chosen to be a matrix with 0 mean
mean = np.mean(nparray2) # Get the mean for the whole matrix
meanByCols = np.mean(nparray2, axis=0) # Get the mean for each column. Returns 2 elements
meanByRows = np.mean(nparray2, axis=1) # get the mean for each row. Returns 3 elements
print('Matrix mean: ')
print(mean)
print('Mean by columns: ')
print(meanByCols)
print('Mean by rows:')
print(meanByRows)1
2
3
4
5
6
7
8
9
10
11
12nparray2 = np.array([[1, 1], [2, 2], [3, 3]]) # Define a 3 x 2 matrix.
nparrayCentered = nparray2 - np.mean(nparray2, axis=0) # Remove the mean for each column
print('Original matrix')
print(nparray2)
print('Centered by columns matrix')
print(nparrayCentered)
print('New mean by column')
print(nparrayCentered.mean(axis=0))1
2
3
4
5
6
7
8
9
10
11
12nparray2 = np.array([[1, 3], [2, 4], [3, 5]]) # Define a 3 x 2 matrix.
nparrayCentered = nparray2.T - np.mean(nparray2.T, axis=0) # Remove the mean for each row
nparrayCentered = nparrayCentered.T # Transpose back the result
print('Original matrix')
print(nparray2)
print('Centered by columns matrix')
print(nparrayCentered)
print('New mean by rows')
print(nparrayCentered.mean(axis=1))