NumPy的主要对象是同种元素的多维数组。这是一个所有的元素都是一种类型、通过一个正整数元组索引的元素表格(通常是元素是数字)。
import numpy as np
i = np.matrix(np.eye(4))
print(type(i))
print(np.linalg.matrix_rank(i))
i = np.eye(4)
print(type(i))
print(np.linalg.matrix_rank(i))
输出:
<class 'numpy.matrixlib.defmatrix.matrix'>
4
<class 'numpy.ndarray'>
4
matrix是array的分支,matrix和array在很多时候都是通用的,你用哪一个都一样。但这时候,官方建议大家如果两个可以通用,那就选择array,因为array更灵活,速度更快,很多人把二维的array也翻译成矩阵。
但是matrix的优势就是相对简单的运算符号,比如两个矩阵相乘,就是用符号*,但是array相乘不能这么用,得用方法.dot() array的优势就是不仅仅表示二维,还能表示3、4、5…维,而且在大部分Python程序里,array也是更常用的。
在python中,可以使用numpy中array创建一个narray对象,我们可以使用dot(a,b)或者@进行普通矩阵乘法,或者使用multipy(a,b)或者*进行数量积操作。
在python创建一个numpy.array([1,2,3])他是一个行向量,shape = (3,)具体来说退化成一个数组,他是可以看做一个行向量或者列向量,具体要看他是在矩阵乘法的左边还是右边,下面进行测试
import numpy as np
a = np.array([[1,0,0],[0,1,0],[0,0,1]]) # (3 * 3)
b = np.array([1,2,3]) # (3,) 抛开线性代数的行向量和列向量,这里他是二者都可以的
c1 = a @ b # 这里是作为一个列向量,(3*3) @ (3,1) = (3,) 结果是一个列向量,但是python中显示都(3,)
c2 = b @ a # 这里是作为一个行向量的, (1 * 3)@ (3 *3) = (1 * 3) 结果还是显示(3,)
print(c2)
输出:
[[1 0 0]
[0 1 0]
[0 0 1]]
[1 2 3]
import numpy as np
a = np.array([[1,0,2],[0,0,1],[0,0,1]]) # (3 * 3)
b = np.array([1,2,1]) # (3,) 抛开线性代数的行向量和列向量,这里他是二者都可以的
c1 = a * b # 相当于[1,2,1]这个数作用于每一列
c2 = b * a # 这里是作为一个行向量的, (1 * 3)@ (3 *3) = (1 * 3) 结果还是显示(3,)
# 这里的 c1 = c2
输出:
[[1 0 2]
[0 0 1]
[0 0 1]]
import numpy as np
a = np.mat([[1,0,0],[0,1,0],[0,0,1]]) # (3 * 3)
b = np.mat([1,2,3]) # 这里的matrix和ndarray是不同的,他是直接输出了(1 × 3)表示这完全是一个行向量
#b = b.reshape(3,1) # 可以进行reshape把行向量变成列向量
c = a * b # 这里注意一下,在matrix中*表示的就是叉乘,但是这里的话 (3×3)* (1*3)出现了矩阵维度不匹配的状况
# 可以把b变成一个列向量就可以了
出现错误:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-22-88c7ec17eabb> in <module>()
4 b = np.mat([1,2,3]) # 这里的matrix和ndarray是不同的,他是直接输出了(1 × 3)表示这完全是一个行向量
5 #b = b.reshape(3,1)
----> 6 c = a * b # 这里注意一下,在matrix中*表示的就是叉乘,但是这里的话 (3×3)* (1*3)出现了矩阵维度不匹配的状况
7 # 可以把b变成一个列向量就可以了
/usr/local/anaconda3/lib/python3.6/site-packages/numpy/matrixlib/defmatrix.py in __mul__(self, other)
307 if isinstance(other, (N.ndarray, list, tuple)) :
308 # This promotes 1-D vectors to row vectors
--> 309 return N.dot(self, asmatrix(other))
310 if isscalar(other) or not hasattr(other, '__rmul__') :
311 return N.dot(self, other)
ValueError: shapes (3,3) and (1,3) not aligned: 3 (dim 1) != 1 (dim 0)
c = b * a # (1*3) @ (3*3) = (1*3)这种是对的
print(c.shape)
**输出: **
(3, 1)
c = np.multiply(a,b) # 在matrix中,我们需要使用multiply函数来计算二个矩阵的数量积
print(c)
输出:
[[1 0 0]
[0 2 0]
[0 0 3]]
import numpy as np
a = np.array([1,1,1])
b = np.array([1,1,1])
c = a @ b # 这里我们知道了python中ndarray默认是一个行向量,但是他也是会发生变化的,比如这里我们@右边的自动变成了一个列向量
print(c)
**输出: **
3
import numpy as np
a = np.mat([[1],[1],[1]]) # a = (3 * 1)
b = np.mat([1,1,1]) # b = (1 * 3)
c1 = a @ b # 经过测试@确实是可以表示叉乘的对于matrix来说,(1 * 3) @ (3 * 1) = (3 * 3)
c2 = a * b # 这个也是表示叉乘的
print(c1==c2)
输出:
[[ True True True]
[ True True True]
[ True True True]]
一种直观的做法就是 (1 × 2)转置和(1 ×3)相乘就可以了。
import numpy as np
a = np.array([1,1]) # (1,2)
b = np.array([1,1,1]) # (1,3)
c = a @ b # 从前面讨论可以知道,这里a是一个行向量,@之后b是一个列向量,也就是c =(1*2) @ (3*1) 当然是出现了类型不匹配了啊!
输出:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-33-9e4dd8a641b5> in <module>()
2 a = np.array([1,1]) # (1,2)
3 b = np.array([1,1,1]) # (1,3)
----> 4 c = a @ b
ValueError: shapes (2,) and (3,) not aligned: 2 (dim 0) != 3 (dim 0)
import numpy as np
a = np.array([[1,1,1],[1,1,1]]) # (2*3)
print(a.T.shape) # (3*2) 这里表示.T
输出:
(3, 2)
import numpy as np
a = np.array([1,1,1])
print(a.shape) # (3,)
print(a.T.shape) # (3,) 这里输出的结果是一样的,表示转置操作对一维向量对numpy中的array不起作用
输出:
(3,)
(3,)
import numpy as np
a = np.mat([[1,1,1]])
print(a.shape) # (1*3) # 这里是起作用的
print(a.T.shape) # (3*1)
输出:
(1, 3)
(3, 1)
所以我们针对上面的问题,我们可以进行以下操作来实现(1*2).T和(1*3)相乘得到(2*3)矩阵
import numpy as np
a = np.array([1,1]) # (1,2)
b = np.array([1,1,1]) # (1,3)
c = (np.matrix(a).T) @ (np.matrix(b)) # 我们可以借助matrix()将numpy中ndarray转换成matrix进行普通矩阵的操作!
print(c)
输出:
[[1 1 1]
[1 1 1]]
我们在实际编程中,可以输出每一步的数据维度,这样我们在进行矩阵乘法的时候,就不会弄混