矩阵
矩阵是numpy.matrix类类型的对象,该类继承自numpy.ndarray,任何针对多维数组的操作,对矩阵同样有效,但是作为子类矩阵又结合其自身的特点,做了必要的扩充,比如:乘法计算、求逆等。
矩阵对象的创建
# 如果copy的值为True(缺省),所得到的矩阵对象与参数中的源容器共享同一份数
# 据,否则,各自拥有独立的数据拷贝。
numpy.matrix(
ary, # 任何可被解释为矩阵的二维容器
copy=True # 是否复制数据(缺省值为True,即复制数据)
)
# 等价于:numpy.matrix(..., copy=False)
# 由该函数创建的矩阵对象与参数中的源容器一定共享数据,无法拥有独立的数据拷贝
numpy.mat(任何可被解释为矩阵的二维容器)
# 该函数可以接受字符串形式的矩阵描述:
# 数据项通过空格分隔,数据行通过分号分隔。例如:'1 2 3; 4 5 6'
numpy.mat(拼块规则)
"""
矩阵创建
"""
import numpy as np
ary = np.arange(1,10,1).reshape((3,3))
res = np.matrix(
ary,
copy=True
)
print(res)
print(np.mat(res))
print(np.mat('1 2 3; 4 5 6'))
[[1 2 3]
[4 5 6]
[7 8 9]]
[[1 2 3]
[4 5 6]
[7 8 9]]
[[1 2 3]
[4 5 6]]
矩阵的乘法运算
# 矩阵的乘法:乘积矩阵的第i行第j列的元素等于
# 被乘数矩阵的第i行与乘数矩阵的第j列的点积
#
# 1 2 6
# X----> 3 5 7
# | 4 8 9
# |
# 1 2 6 31 60 74
# 3 5 7 46 87 116
# 4 8 9 64 120 161
e = np.mat('1 2 6; 3 5 7; 4 8 9')
print(e * e)
矩阵的逆矩阵
若两个矩阵A、B满足:AB = BA = E (E为单位矩阵),则成为A、B为逆矩阵。
e = np.mat('1 2 6; 3 5 7; 4 8 9')
print(e.I)
print(e * e.I)
ndarray提供了方法让多维数组替代矩阵的运算:
a = np.array([
[1, 2, 6],
[3, 5, 7],
[4, 8, 9]])
# 点乘法求ndarray的点乘结果,与矩阵的乘法运算结果相同
k = a.dot(a)
print(k)
# linalg模块中的inv方法可以求取a的逆矩阵
l = np.linalg.inv(a)
print(l)
import numpy as np
prices = np.mat('3 3.2; 3.5 3.6')
totals = np.mat('118.4; 135.2')
persons = prices.I * totals
print(persons)
把逆矩阵的概念推广到非方阵,即称为广义逆矩阵。
案例:斐波那契数列
1 1 2 3 5 8 13 21 34 …
X 1 1 1 1 1 1
1 0 1 0 1 0
--------------------------------
1 1 2 1 3 2 5 3
1 0 1 1 2 1 3 2
F^1 F^2 F^3 F^4 ... f^n
代码
import numpy as np
n = 35
# 使用递归实现斐波那契数列
def fibo(n):
return 1 if n < 3 else fibo(n - 1) + fibo(n - 2)
print(fibo(n))
# 使用矩阵实现斐波那契数列
print(int((np.mat('1. 1.; 1. 0.') ** (n - 1))[0, 0]))
通用函数
裁剪、压缩
数组的裁剪
# 将调用数组中小于和大于下限和上限的元素替换为下限和上限,返回裁剪后的数组,调
# 用原数组保持不变。
ndarray.clip(min=下限, max=上限)
数组的压缩
# 返回由调用数组中满足条件的元素组成的新数组。
ndarray.compress(条件)
案例:
from __future__ import unicode_literals
import numpy as np
a = np.array([10, 20, 30, 40, 50])
print(a)
b = a.clip(min=15, max=45)
print(b)
c = a.compress((15 <= a) & (a <= 45))
print(c)
加法与乘法通用函数
np.add(a, a) # 两数组相加
np.add.reduce(a) # a数组元素累加和
np.add.accumulate(a) # 累加和过程
np.add.outer([10, 20, 30], a) # 外和
np.prod(a) # 累乘
np.cumprod(a) # 累乘过程
np.outer([10, 20, 30], a) # 外积
案例:
a = np.arange(1, 7)
print(a)
b = a + a
print(b)
b = np.add(a, a)
print(b)
c = np.add.reduce(a)
print(c)
d = np.add.accumulate(a)
print(d)
# + 1 2 3 4 5 6
# --------------------
# 10 |11 12 13 14 15 16 |
# 20 |21 22 23 24 25 26 |
# 30 |31 32 33 34 35 36 |
--------------------
f = np.add.outer([10, 20, 30], a)
print(f)
# x 1 2 3 4 5 6
# -----------------------
# 10 |10 20 30 40 50 60 |
# 20 |20 40 60 80 100 120 |
# 30 |30 60 90 120 150 180 |
-----------------------
g = np.outer([10, 20, 30], a)
print(g)
除法与取整通用函数
np.divide(a, b) # a 真除 b
np.floor(a / b) # (真除的结果向下取整)
np.ceil(a / b) # (真除的结果向上取整)
np.trunc(a / b) # (真除的结果截断取整)
np.round(a / b) # (真除的结果四舍五入取整)
案例:
import numpy as np
a = np.array([20, 20, -20, -20])
b = np.array([3, -3, 6, -6])
# 真除
c = np.true_divide(a, b)
c = np.divide(a, b)
c = a / b
print('array:',c)
# 对ndarray做floor操作
d = np.floor(a / b)
print('floor_divide:',d)
# 对ndarray做ceil操作
e = np.ceil(a / b)
print('ceil ndarray:',e)
# 对ndarray做trunc操作
f = np.trunc(a / b)
print('trunc ndarray:',f)
# 对ndarray做around操作
g = np.around(a / b)
print('around ndarray:',g)
位运算通用函数
位异或:
位异或:
c = a ^ b
c = np.bitwise_xor(a, b)
位与:
e = a & b
e = np.bitwise_and(a, b)
位或:
e = a | b
e = np.bitwise_or(a, b)
位反:
e = ~a
e = np.bitwise_or(a, b)
移位:
<< __lshift__ left_shift
>> __rshift__ right_shift
按位异或操作可以很方便的判断两个数据是否同号。
0 ^ 0 = 0
0 ^ 1 = 1
1 ^ 0 = 1
1 ^ 1 = 0
a = np.array([0, -1, 2, -3, 4, -5])
b = np.array([0, 1, 2, 3, 4, 5])
print(a, b)
c = a ^ b
# c = a.__xor__(b)
# c = np.bitwise_xor(a, b)
print(np.where(c < 0)[0])
利用位与运算计算某个数字是否是2的幂
# 1 2^0 00001 0 00000
# 2 2^1 00010 1 00001
# 4 2^2 00100 3 00011
# 8 2^3 01000 7 00111
# 16 2^4 10000 15 01111
# ...
d = np.arange(1, 21)
print(d)
e = d & (d - 1)
e = d.__and__(d - 1)
e = np.bitwise_and(d, d - 1)
print(e)
三角函数通用函数
numpy.sin()
合成方波
一个方波由如下参数的正弦波叠加而成:
y
=
4
π
×
s
i
n
(
x
)
y
=
4
π
3
×
s
i
n
(
3
x
)
.
.
.
.
.
.
y
=
4
π
2
n
−
1
×
s
i
n
(
(
2
n
−
1
)
x
)
y = 4\pi \times sin(x) \\ y = \frac{4\pi}{3} \times sin(3x) \\ ...\\ ...\\ y = \frac{4\pi}{2n-1} \times sin((2n-1)x)
y=4π×sin(x)y=34π×sin(3x)......y=2n−14π×sin((2n−1)x)
曲线叠加的越多,越接近方波。所以可以设计一个函数,接收曲线的数量n作为参数,返回一个矢量函数,该函数可以接收x坐标数组,返回n个正弦波叠加得到的y坐标数组。
x = np.linspace(-2*np.pi, 2*np.pi, 1000)
y = np.zeros(1000)
n = 1000
for i in range(1, n+1):
y += 4 / ((2 * i - 1) * np.pi) * np.sin((2 * i - 1) * x)
mp.plot(x, y, label='n=1000')
mp.legend()
mp.show()