Python与向量

linear algebra
biostatistics
linear algebra
python
Author
Published

Wednesday, March 11, 2020

Python中一般使用numpy库生成一个向量,但其默认生成的是行向量。

import numpy as np
# 行向量
a= np.array([1,2,3,4])
print(a)
[1 2 3 4]

但我们一般使用列向量的形式,因此需要对其做一些处理。有人想,转置处理就可以了,也就是把向量的行索引和列索隐交换位置。但是numpy重的转置方法对于一维数组是无效的:

a= np.array([1,2,3,4])
print(a.transpose()) #从程序的运行结果来看,确实是无效的
[1 2 3 4]

应该如何表示一个列向量呢?

A= np.array([1,2,3,4])
A_t= A[:, np.newaxis] #增加一个维度
print(A_t)
print(A_t.shape) #列向量本身就是二维表示的
[[1]
 [2]
 [3]
 [4]]
(4, 1)

这种做法比较复杂,更直观更简单的实现方法是:显然,我们一直把向量看作是一个维数为1的数组,其实也可以看作是行数为1或列数为1的一个二维数组。而二维数组对应的就是矩阵,因此向量还可以看作是一个特殊的矩阵,即可以把行向量看作是一个1m的特殊矩阵,可以把列向量看作是一个n1的特殊矩阵。

# 在对行向量进行初始化时,使用了numpy中的二维数组的初始化方法,因此在语句中多嵌套了一层中括号
A= np.array([[1,2,3,4]])
print(A)
print(A.T) #此时可以直接通过行向量转置的方法生成对应的列向量
[[1 2 3 4]]
[[1]
 [2]
 [3]
 [4]]

向量的加法

两个维数相同的向量才能进行加法运算,只要将相同位置上的元素对应相加即可,结果向量的维数保持不变。

u= np.array([[1,2,3]]).T
u
v= np.array([[5,6,7]]).T
print(u+v)
[[ 6]
 [ 8]
 [10]]

向量的数乘

向量的数乘就是将参与乘法运算的标量同向量的每个元素分别相乘,以此得到最终的结果向量,结果向量的维数依然保持不变。从几何意义上来看,向量的数乘就是将向量沿着所在直线的方向拉伸相应的倍数,拉伸方向和参与运算的标量符号一致。

u= np.array([[1,2,3]]).T
print(3*u)
[[3]
 [6]
 [9]]

向量间的乘法:内积和外积

向量间的乘法分为内积和外积两种形式。

向量的内积运算:参与内积运算的两个向量必须维数相等,运算规则是先将对应位置上的元素相乘,然后合并相加,最终运算结果是一个标量。可能这样说不太好理解,要是从几何表示上看,内积的意义就非常清晰了。

内积的几何表示u*v= |u||v|cosθ,它表示向量u在向量v方向上的投影长度乘以向量v的模长。需要注意的是,在实际运算向量内积时,无论是行向量间的内积还是列向量间的内积,最终的运算结果都是一样的。

u= np.array([3,5,2])
v= np.array([1,4,7])
# 若使用numpy库中的内积运算函数dot进行运算,传入的参数必须是用一维数组表示的行向量
print(np.dot(u,v)) #一维乘一维,结果还是一维

uC= u[:,np.newaxis]
vC= v[:,np.newaxis]
print(uC)
print(vC)
print(np.dot(uC,vC)) #行数为1的二维数组,即二维数组形式的行向量,报错

u= np.array([[3,5,2]])
v= np.array([[1,4,7]])
print(np.dot(u,v)) #列数为1的二维数组,即二维数组形式的行向量,报错

u= np.array([[3,5,2]]).T
v= np.array([[1,4,7]]).T
print(np.dot(u,v)) #列数为1的二维数组,即二维数组形式的列向量,报错

二维数组形式的向量怎么进行内积运算呢?我们知道二维数组表示下得向量的本质上是矩阵,只不过是行数或列数为1的特殊矩阵。若将这种表示方法下的向量作为传入内积运算函数dot的参数,就需要依据矩阵的乘法法则来计算。

u= np.array([[3,5,2]])
v= np.array([[1,4,7]]).T
print(np.dot(u,v)) #二维乘二维,结果还是二维
[[37]]

向量的外积运算:这里只讨论在二维平面和三维空间中的运算情况。

在二维平面中,与内积类似,外积也有一种表达式:u*v= |u||v|sinθ。在二维平面中,向量的外积表示两个向量张成的平行四边形的“面积”。当然,这个面积要打上引号,因为若两个向量的夹角大于180度,那么向量外积运算所得到的结果为负。

u= np.array([3,5])
v= np.array([1,4])
print(np.cross(u,v)) #一维乘一维,结果还是一维
7
/tmp/ipykernel_7088/2827165229.py:3: DeprecationWarning: Arrays of 2-dimensional vectors are deprecated. Use arrays of 3-dimensional vectors instead. (deprecated in NumPy 2.0)
  print(np.cross(u,v)) #一维乘一维,结果还是一维

而在三维空间中,外积要复杂一点,其计算所得到的结果是一个向量而不是一个数值。其最终得到的结果向量也是有明确的物理含义的,即表示u和v两个向量张成平面的法向量。

x= np.array([3,3,9])
y= np.array([1,4,12])
print(np.cross(x,y))
[  0 -27   9]

向量先数乘后叠加:向量的线性组合

基于向量加法和数量乘法这两类基本运算,将其进行组合应用。针对向量u和v,先求出标量c和向量u的数量积,再求出标量d和向量v的数量积,最后再将二者进行叠加,就得到向量u和v的线性组合cu+dv,这里的标量c和d可以取任意值,包括0。

u= np.array([[1,2,3]]).T
v= np.array([[4,5,6]]).T
w= np.array([[7,8,9]]).T
print(3*u + 4*v + 5*w)
print(u)
u.shape
np.array([[1,2,3]]).shape
print(np.dot(u.T,v.T)) #报错,带有第二个维度无法进行向量内积

进一步思考:我们知道,两个向量相加,在几何上就是将两个向量首尾依次连接,所得到的结果向量就是连接最初的起点和最终的终点的有向连线。我们假定有3个非零的三维列向量u、v和w,讨论以下几种不同的线性组合情况:

  • 第一种情况:cu的所有线性组合构成的图像

    由于标量c可以取0,因而cu的所有线性组合构成的图像可以表示为三维空间中一条穿过原点(0,0,0)的直线,包括原点本身。

  • 第二种情况:cu+dv的所有线性组合构成的图像

    1. 当向量u和向量v不在一条直线上时,即u和v不共线

      cu+dv的所有线性组合构成的图像可以表示为三维空间中的一个通过原点(0,0,0)的二维平面。

    2. 当向量u和向量v处在一条直线上时

      cu+dv的所有线性组合构成的图像可以表示为三维空间中一条穿过原点(0,0,0)的直线,包括原点本身。

  • 第三种情况:cu+dv+ew的所有线性组合构成的图像

    1. 当向量u、v、w不在一个平面上时,cu+dv+ew的所有线性组合构成的图像是整个三维空间。

    2. 当向量u、v、w处在一个平面上时,cu+dv+ew的所有线性组合构成的图像是三维空间中的一个通过原点(0,0,0)的二维平面。

    3. 当向量u、v、w处在一条直线上时,cu+dv+ew的所有线性组合构成的图像是三维空间中一条穿过原点(0,0,0)的直线,包括原点本身。

我们发现,在讨论上述线性组合的多种不同情况时,均反复提到了共线、共面的概念。这些特殊的性质会对一组向量线性组合所得到的结果向量在空间中的位置产生重要影响,它们构成了线性代数中非常重要的概念。后面我们也将使用更加专业的词汇对其进行描述和介绍,即线性相关和线性无关。