从这一节开始我们一起探讨一下numpy的运算。 这一部分需要一定的线性代数的基础。 所以属于中级内容。 感受被数学支配的痛苦吧!!!
本节阅读需20min,无需实操。不要求掌握。
- python numpy运算(1)
- 前言
- 一、基础的向量运算
- numpy.dot()
- numpy.inner()
- numpy.matmul
- 二、线代中的重要运算
- 1. numpy.linalg.det()
- 2. numpy.linalg.solve()
- 3. numpy.linalg.inv()
- 三、广播Broadcast
- 四、总结
所谓“线性”,指的就是如下的数学关系:f(x+y)=f(x)+f(y) 其中,f叫线性算子或线性映射。所谓“代数”,指的就是用符号代替元素和运算,也就是说:我们不关心上面的x,y是实数还是函数,也不关心f是多项式还是微分,我们统一把他们都抽象成一个记号,或是一类矩阵。合在一起,线性代数研究的就是:满足线性关系的线性算子f都有哪几类,以及他们分别都有什么性质
百度的骚话还是那么多。。。
直观的说来就是将我们需要的研究的对象建模,由于客观事物的复杂性。自然是需要多个维度的。所以一般就是向量表示。又因为科学研究推理总是和归纳法逃不开联系,所以我们常常研究向量的集合体,也就是矩阵。
一、基础的向量运算 numpy.dot()numpy.dot() 对于两个一维的数组,计算的是这两个数组对应下标元素的乘积和(数学上称之为内积);对于二维数组,计算的是两个数组的矩阵乘积;对于多维数组,它的通用计算公式如下,即结果数组中的每个元素都是:数组a的最后一维上的所有元素与数组b的倒数第二位上的所有元素的乘积和。
1.都是一维的时候,后面一个会被自动的当做列向量。然后执行矩阵乘法,顾名思义得出来的是矩阵。
2.除了一维特殊之外,需要前面的行和后面的列相等。也就是(mxn)乘(jxm)得出nxj的矩阵。
import numpy as np
a = np.array([[1,2],[3,4]])
b = np.array([[11,12],[13,14]])
print(np.dot(a,b))
#
[[37 40]
[85 92]]
numpy.inner()
numpy.inner() 函数返回一维数组的向量内积。对于更高的维度,它返回最后一个轴上的和的乘积。
只要记住一维和二维我觉得就够了。高级的太抽象。。。
print (np.inner(np.array([1,2,3]),np.array([0,1,0])))
# 等价于 1*0+2*1+3*0
和上面的dot一维的时候一样。
import numpy as np
a = np.array([[1,2], [3,4]])
print ('数组 a:')
print (a)
b = np.array([[11, 12], [13, 14]])
print ('数组 b:')
print (b)
print ('内积:')
print (np.inner(a,b))
# 内积:
[[35 41]
[81 95]]
1*11+2*12, 1*13+2*14
3*11+4*12, 3*13+4*14
相当于自上而下的根据分配律(把左边的当做列向量,右边的当做行向量)降到一维向量和一维向量的内积才运算,然后填充到对应位置上。
numpy.matmulnumpy.matmul 函数返回两个数组的矩阵乘积。 虽然它返回二维数组的正常乘积,但如果任一参数的维数大于2,则将其视为存在于最后两个索引的矩阵的栈,并进行相应广播。
看看就好
import numpy as np
a = [[1,0],[0,1]]
b = [[4,1],[2,2]]
print (np.matmul(a,b))
#
[[4 1]
[2 2]]
其实到最后一维的时候都是内积,但是达到做内积运算的途径不同。最大的不同是顺序问题。
矩阵乘法不满足交换律!!!
二、线代中的重要运算
这里的各个概念不做具体的解释。。。虽然都是线代的基础概念。 但还是看书比较好。百度太碎了。
1. numpy.linalg.det()numpy.linalg.det() 函数计算输入矩阵的行列式。
import numpy as np
a = np.array([[1,2], [3,4]])
print (np.linalg.det(a)) # -2
2. numpy.linalg.solve()
numpy.linalg.solve() 函数给出了矩阵形式的线性方程的解。
线性方程是线代的几乎一半的内容,纯粹的符号推理。。。极有难度。
虽然考试套路固定,但是真要建模使用,太难了点。
3. numpy.linalg.inv()求逆矩阵。手动算逆矩阵还是挺搞人的。 计算机干这事真划算。
import numpy as np
x = np.array([[1,2],[3,4]])
y = np.linalg.inv(x)
print (x)
print (y)
print (np.dot(x,y))
互逆的两个矩阵乘积是单位矩阵。
三、广播Broadcast
广播(Broadcast)是 numpy 对不同形状(shape)的数组进行数值计算的方式, 对数组的算术运算通常在相应的元素上进行。
如果两个数组 a 和 b 形状相同,即满足 a.shape == b.shape,那么 a*b 的结果就是 a 与 b 数组对应位相乘。这要求维数相同,且各维度的长度相同。
a = np.array([1,2,3,4])
b = np.array([10,20,30,40])
c = a * b # *符号重载过,相当于内积或者点乘,要求维度相同。
print (c) # [ 10 40 90 160]
但正如上面所言,矩阵是向量的集合,尤其是在建模的时候。我们想要对矩阵内所有的行向量进行某种处理,比如数值计算。
这个时候就需要广播。不同形状是狭隘的,还是需要匹配的。
import numpy as np
a = np.array([[ 0, 0, 0],
[10,10,10],
[20,20,20],
[30,30,30]])
b = np.array([0,1,2])
print(a + b)
[[ 0 1 2]
[10 11 12]
[20 21 22]
[30 31 32]]
这样就实现了向量的批次化数值处理。 我们完成了一个非常重要的逻辑。 比如说,你是个邪恶的资本家,给员工计算绩效。一个员工一个向量[时间,成果,创新,服从度,好忽悠程度]。 然后所有的员工就是一个矩阵了。 你只需要一个映射向量,就可以数值计算出薪水。。。一键生成,多么愉快!!!
四、总结这一讲讲解的内容属于线代部分比较基础的。
我相信大家看到这里云里雾里。不用担心,不是你的问题。。。
线代毕竟是个很大的学问,后面还带着泛函分析之类的高深内容。
内容不要求掌握。。。但是要了解,知道概念
其实后面的numpy计算都有具体的实例可以学习。反而简单。
线代确实是概念比实践难很多。。。想要理解,百度不现实,老实看书吧。
下一讲,numpy常用的运算。