Numpy中数组array和矩阵matrix区别

时间:2022-10-21 21:24:29

NumPy的主要对象是同种元素的多维数组。这是一个所有的元素都是一种类型、通过一个正整数元组索引的元素表格(通常是元素是数字)。

  • 在NumPy中维度(dimensions)叫做轴(axes),轴的个数叫做秩(rank),和线性代数中的秩不是一样的;
  • 在用python求线代中的秩中,我们用numpy包中的linalg.matrix_rank方法计算矩阵的秩。
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
  1. matrix是array的分支,matrix和array在很多时候都是通用的,你用哪一个都一样。但这时候,官方建议大家如果两个可以通用,那就选择array,因为array更灵活,速度更快,很多人把二维的array也翻译成矩阵。

  2. 但是matrix的优势就是相对简单的运算符号,比如两个矩阵相乘,就是用符号*,但是array相乘不能这么用,得用方法.dot() array的优势就是不仅仅表示二维,还能表示3、4、5…维,而且在大部分Python程序里,array也是更常用的。

numpy使用注意事项

  1. 在python中,可以使用numpy中array创建一个narray对象,我们可以使用dot(a,b)或者@进行普通矩阵乘法,或者使用multipy(a,b)或者*进行数量积操作。

  2. 在python创建一个numpy.array([1,2,3])他是一个行向量,shape = (3,)具体来说退化成一个数组,他是可以看做一个行向量或者列向量,具体要看他是在矩阵乘法的左边还是右边,下面进行测试

1. 叉乘运算

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]]

2. 数量积运算

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]]

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

3.1 下面简单测试一下@符号是否可以在matrix中进行使用

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)矩阵相乘,我们怎么实现了?

一种直观的做法就是 (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)

3.2 .T转置是否对一维向量起作用

3.2.1 首先是numpy中的array(不起作用)

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,)

3.2.2 numpy中matrix(起作用)

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]]

注意:

我们在实际编程中,可以输出每一步的数据维度,这样我们在进行矩阵乘法的时候,就不会弄混