18.矩阵
- numpy.matrix类类型的对象继承自numpy.ndarray,任何针对多维数组的操作,对矩阵同样有效,但是作为子类矩阵又结合其自身的特点,做了必要的扩充,比如:乘法计算,求逆等.
- 矩阵对象的创建可以通过以下三种方式:
numpy.matrix(任何可被解释为矩阵的二维容器,
copy=是否复制数据(缺省值为True,即复制数据))
->矩阵对象
如果copy的值为True(缺省),所得到的矩阵对象与参数中的源容器共享同一份数据,否则,各自拥有独立的数据拷贝,
numpy.mat(任何可被解释为矩阵的二维数组)
等价于
numpy.matrix(...,copy=False)
由该函数创建的矩阵对象与参数中的源容器一定共享数据,无法拥有独立的数据拷贝
numpy.bmat(拼块规则)
->包含若干小矩阵数据的大矩阵,拼接规则由参数指定
以上函数也可以接受字符串形式的矩阵描述:数据项通过空格分隔,数据行通过分号分隔。例如:
'1 2 3; 4 5 6'
/ 1 2 3 \
\ 4 5 6 /
代码:# -*- coding: utf-8 -*- from __future__ import unicode_literals import numpy as np a = np.array([ [1, 2, 6], [3, 5, 7], [4, 8, 9]]) print(a, type(a)) b = np.matrix(a) print(b, type(b)) b += 10 print(b) print(a) c = np.matrix(a, copy=False) print(c, type(c)) c += 10 print(c) print(a) d = np.mat(a) print(d, type(d)) d -= 10 print(d) print(a) e = np.mat('1 2 6; 3 5 7; 4 8 9') print(e) f = np.bmat('b e') print(f) g = np.bmat('b e; e b') print(g) # # 多维数组的乘法:对应位置的元素相乘 # # 1 2 6 1 2 6 1 4 36 # 3 5 7 X 3 5 7 = 9 25 49 # 4 8 9 4 8 9 16 64 81 # h = a * a print(h) # # 矩阵的乘法:乘积矩阵的第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 # i = e * e print(i) j = e.I print(j) print(e * j) # a.I k = a.dot(a) print(k) l = np.linalg.inv(a) print(l)
19.通用函数
- frompyfunc->ufunc对象
def 标量函数(标量参数1, 标量参数2, ...):
...
return 标量返回值1, 标量返回值2, ...
矢量参数1
矢量参数2
...
numpy.frompyfunc(标量函数, 参数个数, 返回值个数)
->矢量函数 # numpy.ufunc类类型的对象,可调用对象
矢量函数(矢量参数1, 矢量参数2, ...)
->矢量返回值1, 矢量返回值2
代码:# -*- coding: utf-8 -*- from __future__ import unicode_literals import numpy as np def foo(x, y): return x + y, x - y, x * y def hum(x): def fun(y): return x + y, x - y, x * y return np.frompyfunc(fun, 1, 1) x, y = 1, 4 print(foo(x, y)) X, Y = np.array([1, 2, 3]), np.array([4, 5, 6]) bar = np.frompyfunc(foo, 2, 3) print(bar(X, Y)) print(np.frompyfunc(foo, 2, 3)(X, Y)) print(hum(100)(X))
- 加法通用函数:add
add.reduce() - 累加和
add.accumulate() -累加和过程
add.reduceat() - 分段累加和
add.outer() -外和
代码:# -*- coding: utf-8 -*- from __future__ import unicode_literals import numpy as np 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) # 0 2 4 # 1 2 3 4 5 6 e = np.add.reduceat(a, [0, 2, 4]) print(e) # + 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)
- 除法通用函数除法通用函数
[5 5 -5 -5]<真除>[2 -2 2 -2] = [2.5 -2.5 -2.5 2.5]
numpy.true_divide()
numpy.divide()
/
[5 5 -5 -5]<地板除>[2 -2 2 -2] = [2 -3 -3 2]
numpy.floor_divide()
//
[5 5 -5 -5]<天花板除>[2 -2 2 -2] = [3 -2 -2 3]
天花板取整(真除的结果):numpy.ceil()
[5 5 -5 -5]<截断除>[2 -2 2 -2] = [2 -2 -2 2]
截断取整(真除的结果):numpy.trunc()
代码:# -*- coding: utf-8 -*- from __future__ import unicode_literals import numpy as np a = np.array([5, 5, -5, -5]) b = np.array([2, -2, 2, -2]) print(a, b) # c = np.true_divide(a, b) # c = np.divide(a, b) c = a / b print(c) # d = np.floor_divide(a, b) d = a // b print(d) e = np.ceil(a / b).astype(int) print(e) f = np.trunc(a / b).astype(int) print(f)
- 取余通用函数
被除数<除以>除数=商...余数
除数 x 商 + 余数 = 被除数
[5 5 -5 -5]<地板除>[2 -2 2 -2] = [2 -3 -3 2]...[1 -1 1 -1]
numpy.remainder()
numpy.mod()
%
[5 5 -5 -5]<截断除>[2 -2 2 -2] = [2 -2 -2 2]...[1 1 -1 -1]
numpy.fmod()
代码:# -*- coding: utf-8 -*- from __future__ import unicode_literals import numpy as np a = np.array([5, 5, -5, -5]) b = np.array([2, -2, 2, -2]) print(a, b) # c = np.remainder(a, b) # c = np.mod(a, b) c = a % b print(c) d = np.fmod(a, b) print(d)
- Numpy将Python语言中针对标量的运算符,通过通用函数加以重载定义,以支持数组形式的矢量运算
斐波那契数列:
1 1 2 3 5 8 13 21 34 ...
f1 = f2 = 1
fn = fn-1 + fn-2, n >= 3
F 1 1 1 1
1 0 1 0
1 1 2 1 3 2
1 0 1 1 2 1
F^1 F^2 F^3 ... F^n-1
1 2 3 4 n
代码# -*- coding: utf-8 -*- from __future__ import unicode_literals import numpy as np n = 35 def fibo(n): return 1 if n < 3 else fibo(n - 1) + fibo(n - 2) print(fibo(n)) fn_1, fn_2 = 0, 1 for i in range(n): fn = fn_1 + fn_2 fn_1, fn_2 = fn, fn_1 print(fn) print(int((np.mat('1. 1.; 1. 0.') ** (n - 1))[0, 0])) r = np.sqrt(5) print(int((((1 + r) / 2) ** n - ((1 - r) / 2) ** n) / r))
- Numpy中所有三角函数都是通用函数
x = Asin(at+pi/2)
y = Bsin(bt)
代码:lissa.py# -*- coding: utf-8 -*- from __future__ import unicode_literals import numpy as np import matplotlib.pyplot as mp t = np.linspace(0, 2 * np.pi, 201) A, a, B, b = 10, 9, 5, 8 x = A * np.sin(a * t + np.pi / 2) y = B * np.sin(b * t) mp.figure('Lissajous', facecolor='lightgray') mp.title('Lissajous', fontsize=20) mp.xlabel('x', fontsize=14) mp.ylabel('y', fontsize=14) mp.tick_params(labelsize=10) mp.grid(linestyle=':') mp.plot(x, y, c='orangered', label='Lissajous') mp.legend() mp.show()
y = 4/(1pi) sin(1x) 2 x 1 - 1
y = 4/(3pi) sin(3x) 2 x 2 - 1
y = 4/(5pi) sin(5x) 2 x 3 - 1
...
k
代码:squr.py# -*- coding: utf-8 -*- from __future__ import unicode_literals import numpy as np import matplotlib.pyplot as mp def squarewave(n): k = np.arange(1, n + 1) def fun(x): return np.sum(4 / ((2 * k - 1) * np.pi) * np.sin((2 * k - 1) * x)) return np.frompyfunc(fun, 1, 1) x = np.linspace(0, 2 * np.pi, 201) y1 = squarewave(1)(x) y2 = squarewave(2)(x) y3 = squarewave(3)(x) y4 = squarewave(10)(x) y5 = squarewave(100)(x) y6 = squarewave(1000)(x) mp.figure('Squarewave', facecolor='lightgray') mp.title('Squarewave', fontsize=20) mp.xlabel('x', fontsize=14) mp.ylabel('y', fontsize=14) mp.tick_params(labelsize=10) mp.grid(linestyle=':') mp.plot(x, y1, label='n=1') mp.plot(x, y2, label='n=2') mp.plot(x, y3, label='n=3') mp.plot(x, y4, label='n=10') mp.plot(x, y5, label='n=100') mp.plot(x, y6, label='n=1000') mp.legend() mp.show()
-
位运算通用函数
位异或:^/__xor__/bitwise_xor
0 ^ 0 = 0
0 ^ 1 = 1
1 ^ 0 = 1
1 ^ 1 = 0
if a^b<0 then a和b异号
代码:bit.py# -*- coding: utf-8 -*- from __future__ import unicode_literals import numpy as np 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]) 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) print(d[e == 0]) # f = d << 1 # f = d.__lshift__(1) f = np.left_shift(d, 1) print(f) # g = d >> 1 # g = d.__rshift__(1) g = np.right_shift(d, 1) print(g)
位与:&/__and__/bitwise_and
0 & 0 = 0
0 & 1 = 0
1 & 0 = 0
1 & 1 = 1
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
...
if a & (a-1) == 0 then a是2的幂
位或:|/__or__/bitwise_or
0 | 0 = 0
0 | 1 = 1
1 | 0 = 1
1 | 1 = 1
位反:~/__not__/bitwise_not
~0 = 1
~1 = 0
移位:<</__lshift__/left_shift
>>/__rshift__/right_shift
左移1位相当于乘2,右移1位相当于除2。
七.numpy的子模块
1.线性代数模块(linalg)
- 逆矩阵和广义逆矩阵如果一个方阵A与另一个方阵B的乘积是一个单位矩阵,那么A和B就互为逆矩阵。
np.linalg.inv(A)->A^-1
将以上有关逆矩阵的定义推广到非方阵,则称为广义逆矩阵。
np.linalg.pinv(A)->A^-1
np.matrix.I -> inv/pinv
代码:inv.py# -*- coding: utf-8 -*- from __future__ import unicode_literals import numpy as np A = np.mat('1 2 3; 8 9 4; 7 6 5') print(A) B = np.linalg.inv(A) print(B) print(A * B) print(A.I) C = np.mat('11 12 13 14; 20 21 22 15; 19 18 17 16') print(C) # D = np.linalg.inv(C) D = np.linalg.pinv(C) print(D) print(C * D) print(C.I) E = np.mat('1 2 3; 4 5 6; 7 8 9') print(E) F = np.linalg.inv(E) print(F) print(E * F)
- 解线性方程组
/ x-2y+z=0
| 2y-8z-8=0
\ -4x+5y+9z+9=0
x-7z-8=0
5x-10y+5z=0
-8x+10y+18z+18=0
-3x+23z+18=0
3x-21z-24=0
2z-6=0
z=3
x=29
29-2y+3=0
y=16
/ x-2y+z=0
| 2y-8z-8=0
\ -4x+5y+9z+9=0
/ 1x + -2y + 1z = 0
| 0x + 2y + -8z = 8
\-4x + 5y + 9z = -9
/ 1 -2 1\ / x \ / 0 \
| 0 2 -8| X | y | = | 8 |
\ -4 5 9/ \ z / \ -9 /
----------- ----- ------
a x b
= np.linalg.lstsq(a, b)[0] -> 拟合
= np.linalg.solve(a, b) -> 解
代码:solve.py# -*- coding: utf-8 -*- from __future__ import unicode_literals import numpy as np a = np.mat('1 -2 1; 0 2 -8; -4 5 9') b = np.mat('0; 8; -9') x = np.linalg.solve(a, b) print(x) x = np.linalg.lstsq(a, b)[0] print(x)
- 特征值和特征向量
对于n阶方阵A,如果存在数a和非零n维列向量x,使得Ax=ax,则称a是矩阵A的一个特征值,x是矩阵A属于特征值a的特征向量
np.linalg.eig(A) -> 特征值数组,特征向量数组
[a1 a2]
[[x11 x12]
[x21 x22]]
代码:eig.py# -*- coding: utf-8 -*- from __future__ import unicode_literals import numpy as np A = np.mat('3 -2; 1 0') print(A) eigvals, eigvecs = np.linalg.eig(A) print(eigvals) print(eigvecs) print(A * eigvecs[:, 0]) print(eigvals[0] * eigvecs[:, 0]) print(A * eigvecs[:, 1]) print(eigvals[1] * eigvecs[:, 1])
- 奇异值分解
主对角线上的元素称为矩阵
M的奇异值,其它元素均为0
|
M = U x S x V
| |
正交矩阵
UxU^T = E = VxV^T
np.linalg.svd(M, full_matrices=False)-> U, 奇异值, V
代码:svd.py# -*- coding: utf-8 -*- from __future__ import unicode_literals import numpy as np M = np.mat('4 11 14; 8 7 -2') print(M) U, sv, V = np.linalg.svd(M, full_matrices=False) print(U * U.T) print(V * V.T) print(sv) S = np.diag(sv) print(S) print(U * S * V)
- 行列式
| a b |
| c d |
ad - bc
| a b c |
| d e f |
| g h i |
a | e f | - b | d f | + c | d e |
| h i | | g i | | g h |
a(ei-fh)-b(di-fg)+c(dh-eg)
np.det(方阵)->行列式的值
代码:det.py# -*- coding: utf-8 -*- from __future__ import unicode_literals import numpy as np A = np.mat('2 1; 3 4') print(A) print(np.linalg.det(A)) B = np.mat('3 2 1; 4 9 8; 5 6 7') print(B) print(np.linalg.det(B))
2.快速傅里叶变换模块(fft)
- 原函数:y = f(x) - 时间/空间域函数
一系列正弦函数的叠加
y = A1sin(w1x+fai1) + A2sin(w2x+fai2) + ... +
Ansin(wnx+fain) + R
n->oo: R->0
[x1, x2, ..., xn]->[y1, y2, ..., yn]
w1->A1, fai1 \
w2->A2, fai2 | A,fai = f'(w) - 频率域函数
... |
wn->An, fain /
f(x) -傅里叶变换-> f'(w)
时空域 频率域
f(x) <-反傅里叶变换- f'(w)
时空域 频率域
np.fft.fftfreq(采样数, 采样周期)->频率序列
np.fft.fft(原函数值序列) -> 目标函数值序列(复数)
复数的模反映了振幅A,辐角反映了初相位fai
np.fft.ifft(目标函数值序列(复数))->原函数值序列
代码:fft.py# -*- coding: utf-8 -*- from __future__ import unicode_literals import numpy as np import numpy.fft as nf import matplotlib.pyplot as mp times = np.linspace(0, 2 * np.pi, 201) sigs1 = 4 / (1 * np.pi) * np.sin(1 * times) sigs2 = 4 / (3 * np.pi) * np.sin(3 * times) sigs3 = 4 / (5 * np.pi) * np.sin(5 * times) sigs4 = 4 / (7 * np.pi) * np.sin(7 * times) sigs5 = 4 / (9 * np.pi) * np.sin(9 * times) sigs6 = sigs1 + sigs2 + sigs3 + sigs4 + sigs5 freqs = nf.fftfreq(times.size, times[1] - times[0]) ffts = nf.fft(sigs6) pows = np.abs(ffts) sigs7 = nf.ifft(ffts).real mp.subplot(121) mp.title('Time Domain', fontsize=16) mp.xlabel('Time', fontsize=12) mp.ylabel('Signal', fontsize=12) mp.tick_params(labelsize=10) mp.grid(linestyle=':') mp.plot(times, sigs1, label='{:.4f}'.format( 1 / (2 * np.pi))) mp.plot(times, sigs2, label='{:.4f}'.format( 3 / (2 * np.pi))) mp.plot(times, sigs3, label='{:.4f}'.format( 5 / (2 * np.pi))) mp.plot(times, sigs4, label='{:.4f}'.format( 7 / (2 * np.pi))) mp.plot(times, sigs5, label='{:.4f}'.format( 9 / (2 * np.pi))) mp.plot(times, sigs6, label='{:.4f}'.format( 1 / (2 * np.pi))) mp.plot(times, sigs7, label='{:.4f}'.format( 1 / (2 * np.pi)), alpha=0.5, linewidth=6) mp.legend() mp.subplot(122) mp.title('Frequency Domain', fontsize=16) mp.xlabel('Frequency', fontsize=12) mp.ylabel('Power', fontsize=12) mp.tick_params(labelsize=10) mp.grid(linestyle=':') mp.plot(freqs[freqs >= 0], pows[freqs >= 0], c='orangered', label='Frequency Spectrum') mp.legend() mp.tight_layout() mp.show()