python矩阵各种运算_【python好用模组-numpy】矩阵数学运算的好工具 #numpy语法详尽整理...

嗨,大家好,

今天要来认识处理矩阵运算的好工具- numpy,

网络上说numpy的好用程度堪比matlab,

可以很方便的做矩阵乘法、求矩阵的逆矩阵,

使一些复杂的数学运算成为可能

安装

numpy不是python的内建模组,

可能会需要另外安装。

但如果你是直接安装anaconda 的话,

那numpy也已经装好了,不必再额外安装

基础概念

首先学习如何宣告一个numpy的矩阵,

要得到一个numpy的矩阵很简单,

用np.array把python的list包起来就可以,

以下是实例:

import numpy as np

List = [[i for i in range(3)] for j in range(4)]

A = np.array(List)

print(A)

结果:

[[0 1 2]

[0 1 2]

[0 1 2]

[0 1 2]]

Matrix 或 ndarray?

在numpy中有两种宣告矩阵的方法:

import numpy as np

List = [[i for i in range(3)] for j in range(4)]

A = np.array(List)

print(A)

print(type(A))

B = np.matrix(List)

print(B)

print(type(B))

结果:

[[0 1 2]

[0 1 2]

[0 1 2]

[0 1 2]]

[[0 1 2]

[0 1 2]

[0 1 2]

[0 1 2]]

根据官方文件NumPy for Matlab users的建议,

使用ndarray会比较好,

有鉴于此,本文接下来的示范以ndarray为主。

另外这份文件也蛮值得一读的,

整理了各项功能对应的指令

重要概念: numpy的加减乘除是对应位置的加减乘除

矩阵 运算 矩阵 = 矩阵相同位置的运算各自做运算

矩阵 运算 常数 = 矩阵每个位置去运算该常数

这是我对numpy概念的统整,

看懂这两句话之后,

numpy的逻辑大致理解八成了,

底下举大量例子辅助说明

一、矩阵 运算 矩阵

譬如说我有两个2*2矩阵A, B,

我要做矩阵加、减法可以直接写A+B,A-B,

但是如果写A*B的话,是直接做对应元素的相乘:

(等一下再说如果真的要做矩阵乘法怎么做)

import numpy as np

A = np.array([

[1,2],

[5,3]])

B = np.array([

[6,2],

[1,7]])

print(A+B)

print(A-B)

print(A*B)

结果:

[[ 7 4]

[ 6 10]]

[[-5 0]

[ 4 -4]]

[[ 6 4]

[ 5 21]]

这边A*B就直接得到单纯相同位置相乘的结果:

[[ 1*6 2*2]

[ 5*1 3*7]]

其实不是只有加减乘除,

任何基础运算都遵循这个规则

譬如说A**B就得到

[[ 1**6 2**2]

[ 5**1 3**7]]

A^B(^是xor运算)就得到

[[ 1^6 2^2]

[ 5^1 3^7]]

再类推一下,A==B并非判断两个矩阵是否相等,

A==B会得到什么呢?

答案:

import numpy as np

A = np.array([

[1,2],

[5,3]])

B = np.array([

[6,2],

[1,7]])

print(A==B)

结果:

[[False True]

[False False]]

答案就是比较相同位置元素的值是否相等。

一开始,我也很不习惯这种设计,

为什么矩阵乘法不直接写A*B呢?不直觉

可是了解之后,我觉得其实这个设计还不错耶~

反而非常单纯,

等于不必去记太多额外的语法,

因为所有运算都遵循这样的规则(真正要记的大概就是矩阵乘法和反矩阵最常用)

二、矩阵 运算 常数

再来看矩阵运算常数的例子,

例如A**3可不是矩阵乘法乘三次的意思,

单纯是每个分量相乘:

import numpy as np

A = np.array([

[1,2],

[5,3]])

print(A**3)

结果:

[[ 1 8]

[125 27]]

类推: 3**A其实就是

[[3**1 3**2]

[3**5 3**3]]

的意思

懂了的话,你也可以尝试推推看print(A>2), print(1/A)应该会得到什么?

印出答案验证你的猜测

常见矩阵运算

相信透过刚刚的介绍,

你应该了解A*B不是矩阵相乘,

1/A或A ** (-1)也不是A的逆矩阵,

这边要示范真的求矩阵相乘与逆矩阵的语法

矩阵相乘、逆矩阵、转置矩阵、判断矩阵是否相等

import numpy as np

A = np.array([

[1,2],

[5,3]])

B = np.array([

[6,2],

[1,7]])

print(A.dot(B)) # 矩阵相乘

print(np.linalg.inv(A)) #求A的反矩阵,若A不可逆会出错

print(A.T) # 求A的转置矩阵

print(np.array_equal(A,B)) # 判断A, B两个矩阵是否相等

结果:

[[ 8 16]

[33 31]]

[[-0.42857143 0.28571429]

[ 0.71428571 -0.14285714]]

[[1 5]

[2 3]]

False

宣告特殊矩阵

numpy的ones, zero, eye分别可以创建全1矩阵、零矩阵、单位矩阵:

import numpy as np

ONE = np.ones((3,4))

O = np.zeros((3,4))

I = np.eye(3)

print(ONE)

print(O)

print(I)

结果:

[[1. 1. 1. 1.]

[1. 1. 1. 1.]

[1. 1. 1. 1.]]

[[0. 0. 0. 0.]

[0. 0. 0. 0.]

[0. 0. 0. 0.]]

[[1. 0. 0.]

[0. 1. 0.]

[0. 0. 1.]]

另外我觉得这两个指令np.arange()和np.linspace()也比较常用,

例子:

import numpy as np

A = np.arange(5,19,2)

B = np.linspace(0,10,7)

print(A)

print(B)

结果:

[ 5. 7.1 9.2 11.3 13.4 15.5 17.6]

[ 0. 1.66666667 3.33333333 5. 6.66666667 8.33333333 10. ]

若你本来熟悉python基础语法的话,

那么np.arange()的语法跟python原生的range()相当接近,

np.arange(5,19,2)是从5~19(不包含19),步长为2的阵列

np.linspace(0,10,7) 则是得到首项未项是0和10,

总有7项的等差数列

矩阵合并、调整大小

numpy中的hstack方法和vstack分别可以做「水平合并」与「垂直合并」,

实例:

import numpy as np

A = np.array([

[1,2],

[5,3]])

B = np.array([

[6,2],

[1,7]])

print(np.hstack((A,B)))

print(np.vstack((A,B)))

结果:

[[1 2 6 2]

[5 3 1 7]]

[[1 2]

[5 3]

[6 2]

[1 7]]

reshape语法可以调整矩阵大小,

实例如下:

import numpy as np

A = np.arange(1,11)

print(A)

B = np.reshape(A,(2,5)) #或写 A.reshape((2,5))

print(B)

A[0] = 20

print(B)

结果:

[ 1 2 3 4 5 6 7 8 9 10]

[[ 1 2 3 4 5]

[ 6 7 8 9 10]]

[[20 2 3 4 5]

[ 6 7 8 9 10]]

这边需注意用reshape产生的矩阵与原矩阵共用记忆体,

若修改A矩阵的值,B矩阵会跟着修改(需留意这个特性,避免日后程序有bug很难找)

若用resize函数则产生的矩阵不共用记忆体

(参考: NumPy 阵列重塑形状和调整大小)

矩阵取子矩阵

这部分若是已经学过python的切片语法的话我觉得就超简单,

语法非常相似,差别在于二维矩阵的切片会用,隔开列、行

实例:

import numpy as np

A = np.arange(1,21)

A.resize((5,4))

print(A)

结果:

[[ 1 2 3 4]

[ 5 6 7 8]

[ 9 10 11 12]

[13 14 15 16]

[17 18 19 20]]

这时我想要取第二列(row)以后、第二~三行(column)的子矩阵怎么办呢?(最上面叫「第一列」、最左边叫「第一行」)

实例:

import numpy as np

A = np.arange(1,21)

A.resize((5,4))

print(A[1:, 1:3])

结果:

[[ 6 7]

[10 11]

[14 15]

[18 19]]

跟python原生的切片语法超像吧?(留给大家自行领悟)

按条件筛选

譬如说我们想返回矩阵A里面大于6的值,

便可以写A[A>6],

实例:

import numpy as np

A = np.arange(1,21)

A.resize((5,4))

print(A[A>6]) # 返回一个一维矩阵

结果:

[ 7 8 9 10 11 12 13 14 15 16 17 18 19 20]

其它好用运算- 求和、求积、累积和

另外,numpy还有一些其它好用的运算sum, product, cumsum,

实例 (这边发现numpy跟原生的python相比,可能有溢位问题):

import numpy as np

"""

实例:a 是一个三维阵列,大小2*3*4

"""

a = [[[1,2,3,2],

[1,2,3,1],

[2,3,4,1]],

[[1,0,2,0],

[2,1,2,0],

[2,1,1,1]]]

"""

np.sum()可以指定要沿着哪一个分量相加,

例如axis=0就是所有a[i][n1][n2]的总和,i=0,1

axis=1就是所有a[n0][i][n2]的总和,i=0,1,2

axis=2就是所有a[n0][n1][i]的总和,i=0,1,2,3

什么都没指定则会将阵列总和算出。

np.prod()效果亦同

"""

print(np.sum(a))

print(np.sum(a,axis=0))

print(np.sum(a,axis=1))

print(np.sum(a,axis=2))

print(np.prod(a))

print(np.prod(a,axis=0))

print(np.prod(a,axis=1))

print(np.prod(a,axis=2))

"""

但需注意numpy可能存在溢位的问题

"""

nums=[14646444444,45656464662,55644445553,4555555555]

print(np.prod(nums)) #溢位

参考资料

Python精讲Numpy基础,大牛笔记详细解释

使用 Python 来认识矩阵 透过numpy

从零开始学资料科学:Numpy 基础入门

NumPy for Matlab users

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值