为了方便自己以后查找,才写了这篇博客,如有错误,希望大家能友好指出!!!
在学习吴恩达机器学习的第三周作业代码(正则化逻辑回归)时,遇到这个问题,特此做个记录。
Numpy中包含数组和矩阵两种基本的数据类型:
array:数组
matrix(可简写为mat):矩阵
matrix是array的分支,matrix和array在表示二维的时候基本上是通用的(例如两者都可以进行转置)。
但在非二维的情况下,有以下显著不同:
matrix仅能表示二维矩阵,即使输入的是一个一维列表,也会把它强制转为二维矩阵。
array不仅能表示二维数组,还能表示1、3、4、5…n维,二维数组也可以叫做矩阵。
Python官方建议在两个都可以使用的场合选择array,因为array更灵活,速度更快。
引用的原文链接 举例:
array([
1, 1]
)是一维数组 #(2,)
array([[
1, 1]]
)是二维数组 #(1,2)
array([[[
1, 1]]]
)是三维数组 #(1,1,2)
这边插入一个矩阵和数组索引的知识
矩阵使用 a[i , j] 来索引具体的某一个元素,使用a[i]来索引某一行
数组a[i] [j]、 a[i , j]都行, ! ! ! 但是一维数组只能a[ i ]来索引
import numpy as np
B = np.array([[1,2,4],[1,4,5]])
C = np.mat(B)
A = np.array([1,2,4])
#ju1=C[1][2] # 会报错
ju1=C[1]
shu1=B[1][2]
ju2=C[1,2]
shu2=B[1,2]
shu3=B[2]
print(f'ju1:{ju1},ju2:{ju2},shu1:{shu1},shu2:{shu2},shu3:{shu3}')
结果:ju1:[[1 4 5]] , ju2:5 , shu1:5 , shu2:5 , shu3:4
1、 * 星乘
(1)矩阵
import numpy as np
a = np.array([[1, 2],
[3,4]])
b = np.array([[5, 6],
[7, 8]])
c=np.mat(a)*np.mat(b)
print (c,type(c))
结果:
[[19 22]
[43 50]] <class 'numpy.matrix'>
(2)数组
import numpy as np
a = np.array([[1, 2],
[3,4]])
b = np.array([[5, 6],
[7, 8]])
c = a * b
print (c,type(c))
结果:
[[ 5 12]
[21 32]] <class 'numpy.ndarray'>
结论:
对矩阵执行矩阵乘法运算
对数组执行对应位置元素相乘(矩阵点乘),就是Hadamard积,如图:
2、.dot
(1)矩阵
import numpy as np
a = np.array([[1, 2],
[3,4]])
b = np.array([[5, 6],
[7, 8]])
c=np.dot(np.mat(a),np.mat(b))
e=np.mat(a).dot(np.mat(b))
print (c,type(c))
print (e,type(e))
结果:
[[19 22]
[43 50]] <class 'numpy.matrix'>
[[19 22]
[43 50]] <class 'numpy.matrix'>
(2)数组
import numpy as np
a = np.array([[1, 2],
[3,4]])
b = np.array([[5, 6],
[7, 8]])
c=np.dot(a,b)
e=a.dot(b)
print (c,type(c))
print (e,type(e))
结果:
[[19 22]
[43 50]] <class 'numpy.ndarray'>
[[19 22]
[43 50]] <class 'numpy.ndarray'>
!!!注意1:对于一维数组
a = np.arange(1,4)
b = np.arange(0,3)
c=np.dot(a,b)
e=np.dot(a,b.T)
print(a,type(a))
print(b,type(b))
print(c,type(c))
print(e,type(e))
print(b.T,b.T.shape)
print(b,b.shape)
结果:是一个标量,对应元素相乘,再相加。(类似于向量点乘(内积))
如果b求一个转置,结果还是这样,一维数组不分行、纵。
只是表示它是一维数组,里面有几个元素。
[1 2 3] <class 'numpy.ndarray'>
[0 1 2] <class 'numpy.ndarray'>
8 <class 'numpy.int32'>
8 <class 'numpy.int32'>
[0 1 2] (3,)
[0 1 2] (3,)
结论:
对数组、矩阵都是执行**矩阵乘法运算**
其中,**一维数组**先是对应位置元素相乘,再相加,得到一个标量。
3、 np.multiply
(1)矩阵
import numpy as np
a = np.array([[1, 2],
[3,4]])
b = np.array([[5, 6],
[7, 8]])
c=np.multiply(np.mat(a),np.matrix(b))
print (c,type(c))
结果:
[[ 5 12]
[21 32]] <class 'numpy.matrix'>
(2)数组
import numpy as np
a = np.array([[1, 2],
[3,4]])
b = np.array([[5, 6],
[7, 8]])
c=np.multiply(a,b)
print (c,type(c))
结果:
[[ 5 12]
[21 32]] <class 'numpy.ndarray'>
结论:
对数组、矩阵都是执行对应元素相乘,也就是Hadamard积。
4、@
(1)矩阵
import numpy as np
a = np.array([[1, 2],
[3,4]])
b = np.array([[5, 6],
[7, 8]])
c = np.mat(a) @ np.mat(b)
print (c,type(c))
结果:
[[19 22]
[43 50]] <class 'numpy.matrix'>
(2)数组
import numpy as np
a = np.array([[1, 2],
[3,4]])
b = np.array([[5, 6],
[7, 8]])
c = a @ b
print (c,type(c))
结果:
[[19 22]
[43 50]] <class 'numpy.ndarray'>
结论:
对矩阵、数组都是执行矩阵乘法运算
! ! ! 注意2:@与.dot一样,
对于m*n的二维数组Amn,当m=1(一维的列表也被强制改为二维数组)时,与一维数组Bt(t代表元素个数)的乘积会报错;当m>=2时,与一维数组相乘,操作如下:
口诀:Amn在左,则Bt为一行,Amn在右,则Bt为一列
情况一:
情况二:
代码示例:
A = np.array([[1, 2],
[3, 4],
[3, 4]])
B = np.array([1,2])
C = np.mat(B)
E = A @ B
F = B.dot(A.reshape(2,3))#array([[1, 2, 3],
# [4, 3, 4]])
# e = np.mat(A) @ C # (3,2)*(1,2)维度不匹配
e = np.mat(A) @ C.T
print(f'数组(3,2)*(2,):{E}',E.shape)
print(f'数组(2,)*(2,3):{F}',F.shape)
print(f'矩阵(3,2)*(2,1):')
print(e)
结果:
数组(3,2)*(2,):[ 5 11 11] (3,)
数组(2,)*(2,3):[ 9 8 11] (3,)
矩阵(3,2)*(2,1):
[[ 5]
[11]
[11]]
5、总结
对应元素相乘:np.multiply(a,b)
矩阵乘法:np.dot(a,b) 或 a.dot(b) 或用 a @ b 或 np.matmul(a,b)
唯独注意:*,在 np.array 中为对应元素乘法,在 np.matrix 中为矩阵乘法!
还要注意一维数组的一些应用;一般我们在使用的时候,
矩阵使用 * 作【矩阵乘法】
数组使用 np.dot(a,b) 或 a.dot(b) 或用 a @ b 作【矩阵乘法】
矩阵使用 np.multiply(a,b) 作【对应元素相乘】
数组用 * 是【对应元素相乘】