矩陣
- 矩阵是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 /
#mat.py
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')
# 多維數組的乘法:對應元素相乘
h = a * a
print('h等於\n', h)
# 矩陣相乘:乘積矩陣的第i行第j列元素等於被乘矩陣的第i行於乘數矩陣的第j列的點積
i = e * e
print('i等於\n', i)
j = e.I
print('e的逆矩陣為\n', j)
print(j * e)
k = a.dot(a) # 數組使用矩陣乘法
l = np.linalg.inv(a) # 數組使用逆矩陣
[[1 2 6]
[3 5 7]
[4 8 9]] <class 'numpy.ndarray'>
[[1 2 6]
[3 5 7]
[4 8 9]] <class 'numpy.matrixlib.defmatrix.matrix'>
[[11 12 16]
[13 15 17]
[14 18 19]]
[[1 2 6]
[3 5 7]
[4 8 9]]
[[1 2 6]
[3 5 7]
[4 8 9]] <class 'numpy.matrixlib.defmatrix.matrix'>
[[11 12 16]
[13 15 17]
[14 18 19]]
[[11 12 16]
[13 15 17]
[14 18 19]]
[[11 12 16]
[13 15 17]
[14 18 19]] <class 'numpy.matrixlib.defmatrix.matrix'>
[[1 2 6]
[3 5 7]
[4 8 9]]
[[1 2 6]
[3 5 7]
[4 8 9]]
[[1 2 6]
[3 5 7]
[4 8 9]]
[[11 12 16 1 2 6]
[13 15 17 3 5 7]
[14 18 19 4 8 9]]
h等於
[[ 1 4 36]
[ 9 25 49]
[16 64 81]]
i等於
[[ 31 60 74]
[ 46 87 116]
[ 64 120 161]]
e的逆矩陣為
[[-0.73333333 2. -1.06666667]
[ 0.06666667 -1. 0.73333333]
[ 0.26666667 0. -0.06666667]]
[[ 1.00000000e+00 1.77635684e-15 3.55271368e-15]
[ 0.00000000e+00 1.00000000e+00 -1.11022302e-16]
[ 0.00000000e+00 0.00000000e+00 1.00000000e+00]]
通用函数
1. frompyfunc->ufunc对象
def 标量函数(标量参数1, 标量参数2, ...):
...
return 标量返回值1, 标量返回值2, ...
矢量参数1
矢量参数2
...
numpy.frompyfunc(标量函数, 参数个数, 返回值个数)
->矢量函数 # numpy.ufunc类类型的对象,可调用对象
矢量函数(矢量参数1, 矢量参数2, ...)
->矢量返回值1, 矢量返回值2
# ufunc.py
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))
(5, -3, 4)
(array([5, 7, 9], dtype=object), array([-3, -3, -3], dtype=object), array([4, 10, 18], dtype=object))
(array([5, 7, 9], dtype=object), array([-3, -3, -3], dtype=object), array([4, 10, 18], dtype=object))
[(101, 99, 100) (102, 98, 200) (103, 97, 300)]
2. 加法通用函数:add
add.reduce() - 累加和
add.accumulate() - 累加和过程
add.reduceat() - 分段累加和
add.outer() - 外和
# add.py
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)
e = np.add.reduceat(a, [0, 2, 4]) # 按照下標分段
print(e)
f = np.add.outer([10, 20, 30], a)
print(f)
g = np.outer([10, 20, 30], a) # 不加add的話是外積
print(g)
[1 2 3 4 5 6]
[ 2 4 6 8 10 12]
[ 2 4 6 8 10 12]
21
[ 1 3 6 10 15 21]
[ 3 7 11]
[[11 12 13 14 15 16]
[21 22 23 24 25 26]
[31 32 33 34 35 36]]
[[ 10 20 30 40 50 60]
[ 20 40 60 80 100 120]
[ 30 60 90 120 150 180]]
3. 除法通用函数
[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()
# div.py
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)
[ 5 5 -5 -5] [ 2 -2 2 -2]
[ 2.5 -2.5 -2.5 2.5]
[ 2 -3 -3 2]
[ 3 -2 -2 3]
[ 2 -2 -2 2]
4. 取余通用函数
被除数/除数=商...余数
除数 * 商 + 余数 = 被除数
[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()
Numpy将Python语言中针对标量的运算符,通过通用函数加以重载定义,以支持数组形式的矢量运算。
# fib.py
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))
9227465
9227465
9227465
5. Numpy中的所有三角函数都是通用函数
x = Asin(at+pi/2)
y = Bsin(bt)
# lissa.py
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
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()
7. 位运算通用函数
位异或:^/__xor__/bitwise_xor
0 ^ 0 = 0
0 ^ 1 = 1
1 ^ 0 = 1
1 ^ 1 = 0
if a^b<0 then a和b异号
位与:&/__and__/bitwise_and
0 & 0 = 0
0 & 1 = 0
1 & 0 = 0
1 & 1 = 1
# 判断是否为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
...
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。
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(c)
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)
[ 0 -1 2 -3 4 -5] [0 1 2 3 4 5]
[ 0 -2 0 -2 0 -2]
[1 3 5]
[ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20]
[ 0 0 2 0 4 4 6 0 8 8 10 8 12 12 14 0 16 16 18 16]
[ 1 2 4 8 16]
[ 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40]
[ 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10]
线性代数模块(linalg)
1. 逆矩阵和广义逆矩阵
- 如果一个方阵A与另一个方阵B的乘积是一个单位矩阵,那么A和B就互为逆矩阵。
np.linalg.inv(A)->A^-1 - 将以上有关逆矩阵的定义推广到非方阵,则称为广义逆矩阵。
np.linalg.pinv(A)->A^-1
np.matrix.I -> inv/pinv
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)
[[1 2 3]
[8 9 4]
[7 6 5]]
[[-0.4375 -0.16666667 0.39583333]
[ 0.25 0.33333333 -0.41666667]
[ 0.3125 -0.16666667 0.14583333]]
[[ 1.00000000e+00 2.77555756e-17 -5.55111512e-17]
[ 0.00000000e+00 1.00000000e+00 2.22044605e-16]
[ 0.00000000e+00 1.94289029e-16 1.00000000e+00]]
[[-0.4375 -0.16666667 0.39583333]
[ 0.25 0.33333333 -0.41666667]
[ 0.3125 -0.16666667 0.14583333]]
[[11 12 13 14]
[20 21 22 15]
[19 18 17 16]]
[[-0.18055556 -0.08333333 0.23611111]
[-0.04305556 0.04166667 -0.00138889]
[ 0.09444444 0.16666667 -0.23888889]
[ 0.1625 -0.125 0.0375 ]]
[[ 1.00000000e+00 2.22044605e-16 -3.33066907e-16]
[ 1.77635684e-15 1.00000000e+00 -1.88737914e-15]
[ 1.77635684e-15 8.88178420e-16 1.00000000e+00]]
[[-0.18055556 -0.08333333 0.23611111]
[-0.04305556 0.04166667 -0.00138889]
[ 0.09444444 0.16666667 -0.23888889]
[ 0.1625 -0.125 0.0375 ]]
[[1 2 3]
[4 5 6]
[7 8 9]]
[[ 3.15251974e+15 -6.30503948e+15 3.15251974e+15]
[-6.30503948e+15 1.26100790e+16 -6.30503948e+15]
[ 3.15251974e+15 -6.30503948e+15 3.15251974e+15]]
[[ 0. 1. -0.5]
[ 0. 2. -1. ]
[ 0. 3. 2.5]]
2. 解线性方程组
$$
\left( \begin{array}{l}
x - 2y + z = 0\
2y - 8z - 8 = 0\
- 4x + 5y + 9z + 9 = 0
\end{array} \right.
$$
$$
\left( \begin{array}{l}
1x + - 2y + 1z = 0\
0x + 2y + - 8z = 8\
- 4x + 5y + 9z = - 9
\end{array} \right.
$$
$$
\left( {\begin{array}{{20}{c}}
1&{ - 2}&1\
0&2&{ - 8}\
{ - 4}&5&9
\end{array}} \right) \times \left( {\begin{array}{{20}{c}}
x\
y\
z
\end{array}} \right) = \left( {\begin{array}{*{20}{c}}
0\
8\
{ - 9}
\end{array}} \right)
$$
a x b
= np.linalg.lstsq(a, b)[0] -> 拟合
= np.linalg.solve(a, b) -> 解
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)
[[29.]
[16.]
[ 3.]]
[[29.]
[16.]
[ 3.]]
/Users/haoen110/miniconda3/lib/python3.7/site-packages/ipykernel_launcher.py:6: FutureWarning: `rcond` parameter will change to the default of machine precision times ``max(M, N)`` where M and N are the input matrix dimensions.
To use the future default and silence this warning we advise to pass `rcond=None`, to keep using the old, explicitly pass `rcond=-1`.
3. 特征值和特征向量
- 对于n阶方阵A,如果存在数a和非零n维列向量x,使得Ax=ax,则称a是矩阵A的一个特征值,x是矩阵A属于特征值a的特征向量
np.linalg.eig(A) -> 特征值数组,特征向量数组
[a1 a2]
[[x11 x12]
[x21 x22]]
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])
[[ 3 -2]
[ 1 0]]
[2. 1.]
[[0.89442719 0.70710678]
[0.4472136 0.70710678]]
[[1.78885438]
[0.89442719]]
[[1.78885438]
[0.89442719]]
[[0.70710678]
[0.70710678]]
[[0.70710678]
[0.70710678]]
4. 奇异值分解
- 主对角线上的元素称为矩阵M的奇异值,其它元素均为0
|
M = U x S x V
| |
正交矩阵
UxU^T = E = VxV^T
np.linalg.svd(M, full_matrices=False)-> U, 奇异值, V
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)
[[ 4 11 14]
[ 8 7 -2]]
[[1.0000000e+00 3.2123061e-17]
[3.2123061e-17 1.0000000e+00]]
[[ 1.00000000e+00 -6.16790569e-18]
[-6.16790569e-18 1.00000000e+00]]
[18.97366596 9.48683298]
[[18.97366596 0. ]
[ 0. 9.48683298]]
[[ 4. 11. 14.]
[ 8. 7. -2.]]
5. 行列式
np.det(方阵)->行列式的值
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 1]
[3 4]]
5.000000000000001
[[3 2 1]
[4 9 8]
[5 6 7]]
47.999999999999986
快速傅里叶变换模块(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(目标函数值序列(复数))->原函数值序列
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()
- 基于傅里叶变换的频域滤波
____________________IFFT_____________________
| |
v |
高能信号? FFT 频域滤波 |
>含噪信号----->含噪频谱---------->高能频谱
低能噪声/
import numpy as np
import numpy.fft as nf
import scipy.io.wavfile as wf
import matplotlib.pyplot as mp
sample_rate, noised_sigs = wf.read(
'../data/noised.wav')
noised_sigs = noised_sigs / 2 ** 15
times = np.arange(len(noised_sigs)) / sample_rate
freqs = nf.fftfreq(times.size, 1 / sample_rate)
noised_ffts = nf.fft(noised_sigs)
noised_pows = np.abs(noised_ffts)
fund_freq = np.abs(freqs[noised_pows.argmax()])
print(fund_freq)
noised_indices = np.where(np.abs(freqs) != fund_freq)
filter_ffts = noised_ffts.copy()
filter_ffts[noised_indices] = 0
filter_pows = np.abs(filter_ffts)
filter_sigs = nf.ifft(filter_ffts).real
wf.write('../data/filter.wav', sample_rate,
(filter_sigs * 2 ** 15).astype(np.int16))
mp.figure('Filter', facecolor='lightgray')
mp.subplot(221)
mp.title('Time Domain', fontsize=16)
mp.ylabel('Signal', fontsize=12)
mp.tick_params(labelsize=10)
mp.grid(linestyle=':')
mp.plot(times[:178], noised_sigs[:178],
c='orangered', label='Noised')
mp.legend()
mp.subplot(222)
mp.title('Frequency Domain', fontsize=16)
mp.ylabel('Power', fontsize=12)
mp.tick_params(labelsize=10)
mp.grid(linestyle=':')
mp.semilogy(freqs[freqs >= 0],
noised_pows[freqs >= 0], c='limegreen',
label='Noised')
mp.legend()
mp.subplot(223)
mp.xlabel('Time', fontsize=12)
mp.ylabel('Signal', fontsize=12)
mp.tick_params(labelsize=10)
mp.grid(linestyle=':')
mp.plot(times[:178], filter_sigs[:178],
c='hotpink', label='Filter')
mp.legend()
mp.subplot(224)
mp.xlabel('Frequency', fontsize=12)
mp.ylabel('Power', fontsize=12)
mp.tick_params(labelsize=10)
mp.grid(linestyle=':')
mp.plot(freqs[freqs >= 0], filter_pows[freqs >= 0],
c='dodgerblue', label='Filter')
mp.legend()
mp.tight_layout()
mp.show()
1000.0
随机数模块(random)
生成服从特定统计规律的随机数序列。
1. 二项分布
np.random.binomial(n, p, size)
- 产生size个随机数,每个随机数来自n次尝试中的成功次数,其中每次尝试成功的概率为p。
# 猜硬币游戏:初始筹码1000,每轮猜9次,猜对5次及5次以上为赢,筹码加1,否则为输,筹码减1,求10000轮的过程中手中筹码的变化。
# 代码:bi.py
import numpy as np
import matplotlib.pyplot as mp
outcomes = np.random.binomial(9, 0.5, 10000)
chips = [1000]
for outcome in outcomes:
if outcome >= 5:
chips.append(chips[-1] + 1)
else:
chips.append(chips[-1] - 1)
chips = np.array(chips)
mp.figure('Binomial Distribution',
facecolor='lightgray')
mp.title('Binomial Distribution', fontsize=20)
mp.xlabel('Round', fontsize=14)
mp.ylabel('Chip', fontsize=14)
mp.tick_params(labelsize=12)
mp.grid(linestyle=':')
o, h, l, c = 0, chips.argmax(), chips.argmin(), chips.size - 1
if chips[o] < chips[c]:
color = 'orangered'
elif chips[c] < chips[o]:
color = 'limegreen'
else:
color = 'dodgerblue'
mp.plot(chips, c=color, label='Chip')
mp.axhline(y=chips[o], linestyle='--',
color='deepskyblue', linewidth=1)
mp.axhline(y=chips[h], linestyle='--',
color='crimson', linewidth=1)
mp.axhline(y=chips[l], linestyle='--',
color='seagreen', linewidth=1)
mp.axhline(y=chips[c], linestyle='--',
color='orange', linewidth=1)
mp.legend()
mp.show()
2. 超几何分布
np.random.hypergeometric(ngood, nbad, nsample, size)
- 产生size个随机数,每个随机数来自随机抽取nsample个样本中好样本的个数,总样本由ngood个好样本和nbad个坏样本组成
# 模球游戏:将25个好球和1个坏球放在一起,每次模3个球,全为好球加1分,只要摸到了坏球减6分,求100轮的过程中分值的变化。
# 代码:hyper.py
import numpy as np
import matplotlib.pyplot as mp
outcomes = np.random.hypergeometric(25, 1, 3, 100)
scores = [0]
for outcome in outcomes:
if outcome == 3:
scores.append(scores[-1] + 1)
else:
scores.append(scores[-1] - 6)
scores = np.array(scores)
mp.figure('Hypergeometric Distribution',
facecolor='lightgray')
mp.title('Hypergeometric Distribution', fontsize=20)
mp.xlabel('Round', fontsize=14)
mp.ylabel('Score', fontsize=14)
mp.tick_params(labelsize=12)
mp.grid(linestyle=':')
o, h, l, c = 0, scores.argmax(), scores.argmin(), scores.size - 1
if scores[o] < scores[c]:
color = 'orangered'
elif scores[c] < scores[o]:
color = 'limegreen'
else:
color = 'dodgerblue'
mp.plot(scores, c=color, label='Score')
mp.axhline(y=scores[o], linestyle='--',
color='deepskyblue', linewidth=1)
mp.axhline(y=scores[h], linestyle='--',
color='crimson', linewidth=1)
mp.axhline(y=scores[l], linestyle='--',
color='seagreen', linewidth=1)
mp.axhline(y=scores[c], linestyle='--',
color='orange', linewidth=1)
mp.legend()
mp.show()
3. 标准正态分布
np.random.norm(size)
- `产生size个随机数,服从标准正态(平均值=0, 标准差=1)分布。
- 概率密度:$f(x) = \frac{{{e^{ - \frac{{{{(x - \mu )}^2}}}{{2{\sigma ^2}}}}}}}{{\sigma \sqrt {2\pi } }}$
# norm.py
import numpy as np
import matplotlib.pyplot as mp
samples = np.random.normal(size=10000)
mp.figure('Normal Distribution', facecolor='lightgray')
mp.title('Normal Distribution', fontsize=20)
mp.xlabel('Sample', fontsize=14)
mp.ylabel('Occurrence', fontsize=14)
mp.tick_params(labelsize=12)
mp.grid(axis='y', linestyle=':')
bins = mp.hist(samples, 100, normed=True,
edgecolor='steelblue',
facecolor='deepskyblue',
label='Normal')[1]
probs = np.exp(-bins ** 2 / 2) / np.sqrt(2 * np.pi)
mp.plot(bins, probs, 'o-', c='orangered',
label='Probability')
mp.legend()
mp.show()
杂项
1. 排序
联合间接排序
numpy.lexsort((参考序列, 待排序列))
-> 有序索引
[张三 李四 王五 赵六]
[70 60 80 70]<-[30 20 30 20]numpy.sort_complex(复数数组)
- 按照实部的升序排列,对于实部相同的元素,参考虚部的升序,直接返回排序后的结果数组。
numpy.searchsorted(有序序列, 待插序列)
->位置数组- 表示将待插序列中的元素插入到有序序列中的哪些位置处,结果依然有序
numpy.insert(被插序列, 位置序列, 待插序列)
->将待插序列中的元素- 按照位置序列中的位置,插入到被插序列中,返回插入后的结果
# sort.py
import numpy as np
ages = np.array([30, 20, 30, 20])
scores = np.array([70, 60, 80, 70])
names = np.array(['zhangsan', 'lisi', 'wangwu', 'zhaoliu'])
# 按照成绩的升序打印姓名,成绩相同的按照年龄的升序排列
print(np.take(names, np.lexsort((ages, scores))))
compleies = scores + ages * 1j
print(compleies)
sorted_compleies = np.sort_complex(compleies)
print(sorted_compleies)
# 0 1 2 3 4 5 6
a = np.array([1, 2, 4, 5, 6, 8, 9])
b = np.array([7, 3])
c = np.searchsorted(a, b)
print(c)
d = np.insert(a, c, b)
print(d)
['lisi' 'zhaoliu' 'zhangsan' 'wangwu']
[70.+30.j 60.+20.j 80.+30.j 70.+20.j]
[60.+20.j 70.+20.j 70.+30.j 80.+30.j]
[5 2]
[1 2 3 4 5 6 7 8 9]
2. 插值
import scipy.interpolate as si
si.interp1d(离散水平坐标, 离散垂直坐标, kind=插值算法(缺省为线性插值)) -> 插值器
插值器(水平坐标)->垂直坐标
import numpy as np
import scipy.interpolate as si
import matplotlib.pyplot as mp
min_x, max_x = -2.5, 2.5
con_x = np.linspace(min_x, max_x, 1001)
con_y = np.sinc(con_x)
dis_x = np.linspace(min_x, max_x, 11)
dis_y = np.sinc(dis_x)
# 线性插值
linear = si.interp1d(dis_x, dis_y)
lin_x = np.linspace(min_x, max_x, 51)
lin_y = linear(lin_x)
# 三次样条插值
cubic = si.interp1d(dis_x, dis_y, kind='cubic')
cub_x = np.linspace(min_x, max_x, 51)
cub_y = cubic(cub_x)
mp.figure('Interpolation', facecolor='lightgray')
mp.subplot(221)
mp.title('Continuous', fontsize=16)
mp.ylabel('y', fontsize=12)
mp.tick_params(labelsize=10)
mp.grid(linestyle=':')
mp.plot(con_x, con_y, c='hotpink',
label='Continuous')
mp.legend()
mp.subplot(222)
mp.title('Discrete', fontsize=16)
mp.tick_params(labelsize=10)
mp.grid(linestyle=':')
mp.scatter(dis_x, dis_y, c='orangered', s=80,
label='Discrete')
mp.legend()
mp.subplot(223)
mp.title('Linear', fontsize=16)
mp.xlabel('x', fontsize=12)
mp.ylabel('y', fontsize=12)
mp.tick_params(labelsize=10)
mp.grid(linestyle=':')
mp.plot(lin_x, lin_y, 'o-', c='limegreen',
label='Linear')
mp.scatter(dis_x, dis_y, c='orangered', s=80,
zorder=3)
mp.legend()
mp.subplot(224)
mp.title('Cubic', fontsize=16)
mp.xlabel('x', fontsize=12)
mp.tick_params(labelsize=10)
mp.grid(linestyle=':')
mp.plot(cub_x, cub_y, 'o-', c='dodgerblue',
label='Cubic')
mp.scatter(dis_x, dis_y, c='orangered', s=80,
zorder=3)
mp.legend()
mp.tight_layout()
mp.show()
3. 积分
import scipy.integrate as si
si.quad(积分函数, 积分下限, 积分上限)->积分值, 最大误差
import numpy as np
import scipy.integrate as si
import matplotlib.pyplot as mp
import matplotlib.patches as mc
# 定义函数
def f(x):
return 2 * x ** 2 + 3 * x + 4
# 确定x范围
a, b = -5, 5
x1 = np.linspace(a, b, 1001)
y1 = f(x1)
# 用scipy来计算积分
area = si.quad(f, a, b)[0]
print(area)
# 手动分割小梯形来计算面积,n越大,越接近真实值
n = 10
x2 = np.linspace(a, b, n + 1)
y2 = f(x2)
area = 0
for i in range(n):
area += (y2[i] + y2[i + 1]) * (x2[i + 1] - x2[i]) / 2
print(area)
# 绘制函数图
mp.figure('Integral', dpi=120, facecolor='lightgray')
mp.title('Integral', fontsize=20)
mp.xlabel('x', fontsize=14)
mp.ylabel('y', fontsize=14)
mp.tick_params(labelsize=10)
mp.grid(linestyle=':')
mp.plot(x1, y1, c='orangered', linewidth=6,
label=r'$y=2x^2+3x+4$', zorder=0)
for i in range(n):
mp.gca().add_patch(mc.Polygon([
[x2[i], 0], [x2[i], y2[i]],
[x2[i + 1], y2[i + 1]], [x2[i + 1], 0]],
fc='deepskyblue', ec='dodgerblue',
alpha=0.5))
mp.legend()
mp.show()
206.66666666666669
210.0
4. 图像
scipy.ndimage中提供了一些简单的图像处理,如高斯模糊、任意角度旋转、边缘识别等功能。
import numpy as np
import scipy.misc as sm # 杂项工具
import scipy.ndimage as sn
import matplotlib.pyplot as mp
original = sm.imread('../data/lily.jpg', True) # True就是黑白
print(original.shape, original.dtype)
median = sn.median_filter(original, (31, 31)) # 中值滤波,消除细节干扰、模糊化
rotate = sn.rotate(original, 45)
prewitt = sn.prewitt(original)
mp.figure('Image', dpi=120, facecolor='lightgray')
mp.subplot(221)
mp.title('Original', fontsize=16)
mp.axis('off')
mp.imshow(original, cmap='gray')
mp.subplot(222)
mp.title('Median', fontsize=16)
mp.axis('off')
mp.imshow(median, cmap='gray')
mp.subplot(223)
mp.title('Rotate', fontsize=16)
mp.axis('off')
mp.imshow(rotate, cmap='gray')
mp.subplot(224)
mp.title('Prewitt', fontsize=16)
mp.axis('off')
mp.imshow(prewitt, cmap='gray')
mp.tight_layout()
mp.show()
/Users/haoen110/miniconda3/lib/python3.7/site-packages/ipykernel_launcher.py:6: DeprecationWarning: `imread` is deprecated!
`imread` is deprecated in SciPy 1.0.0, and will be removed in 1.2.0.
Use ``imageio.imread`` instead.
(517, 690) float32
5. 金融
import numpy as np
# 终值 = fv(利率, 期数, 每期支付, 现值)
# 将1000元以1%的年利率存入银行5年,每年加存100元,
# 到期后本息合计多少钱?
fv = np.fv(0.01, 5, -100, -1000) # 凡是掏钱,都是负数
print(round(fv, 2))
# 现值 = pv(利率, 期数, 每期支付, 终值)
# 将多少钱以1%的年利率存入银行5年,每年加存100元,
# 到期后本息合计fv元?
pv = np.pv(0.01, 5, -100, fv)
print(pv)
# 净现值 = npv(利率, 现金流)
# 将1000元以1%的年利率存入银行5年,每年加存100元,
# 相当于一次性存入多少钱?
npv = np.npv(0.01, [-1000, -100, -100, -100, -100, -100])
print(round(npv, 2))
fv = np.fv(0.01, 5, 0, npv)
print(round(fv, 2))
# 内部收益率 = irr(现金流)
# 将1000元存入银行5年,以后逐年提现100元、200元、
# 300元、400元、500元,银行利率达到多少,可在最后
# 一次提现后偿清全部本息,即净现值为0元?
irr = np.irr([-1000, 100, 200, 300, 400, 500])
print(round(irr, 2))
npv = np.npv(irr, [-1000, 100, 200, 300, 400, 500])
print(npv)
# 每期支付 = pmt(利率, 期数, 现值)
# 以1%的年利率从银行贷款1000元,分5年还清,
# 平均每年还多少钱?
pmt = np.pmt(0.01, 5, 1000)
print(round(pmt, 2))
# 期数 = nper(利率, 每期支付, 现值)
# 以1%的年利率从银行贷款1000元,平均每年还pmt元,
# 多少年还清?
nper = np.nper(0.01, pmt, 1000)
print(int(nper))
# 利率 = rate(期数, 每期支付, 现值, 终值)
# 从银行贷款1000元,平均每年还pmt元,nper年还清,
# 年利率多少?
rate = np.rate(nper, pmt, 1000, 0)
print(round(rate, 2))
1561.11
-1000.0
-1485.34
1561.11
0.12
0.0
-206.04
5
0.01
原文地址:https://www.cnblogs.com/haoenwei/p/10990036.html
时间: 2024-10-10 07:49:55