1)矩阵求逆
如果一个n阶方阵A与另一个n阶方阵B的乘积是一个单位阵,那么就称A与B互为逆矩阵。
A B = E
A = B^-1
np.linalg.inv(A)->A^-1,仅限于方阵,狭义逆矩阵
np.linalg.pinv(A)->A^-1,不仅限于方阵,广义逆矩阵
矩阵的I属性,对应就是广义逆矩阵
# -*- 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)
C = A[:2]
print(C)
D = np.linalg.pinv(C)
print(D)
print(C * D)
E = np.arange(1, 10).reshape(3, 3)
print(E)
F = np.linalg.inv(E)
print(F)
print(E * F)
2)线性方程组
x-2y+z=0
2y-8z-8=0
-4x+5y+9z+9 = 0
--------------------
4x-8y+4z=0
-3y+13z+9=0
2y-8z-8=0
--------------------
-6y+26z+18 = 0
6y-24z-24=0
--------------------
2z-6=0 -> z = 3
2y-24-8=0 -> y =16
x-32+3=0 -> x = 29
-----------------------
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)
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import numpy as np
a = np.mat('1 -2 1; 0 2 -8; -4 5 9')
print(a)
b = np.mat('0; 8; -9')
print(b)
x = np.linalg.solve(a, b)
print(x)
x = np.linalg.lstsq(a, b)[0]
print(x)
3)特征值和特征向量
对于n阶方阵A,如果存在数a和非零n维列向量x,满足Ax=ax,则称a是矩阵A的一个特征值,x是矩阵A属于特征值a的特征向量
np.linalg.eig(A) -> a, x
x中的一列是一个与a中相应特征值对应的特征向量
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import numpy as np
A = np.mat('3 -2; 1 0')
print(A)
a, x = np.linalg.eig(A)
print(a)
print(x)
print(A * x[:, 0], a[0] * x[:, 0], sep='\n')
print(A * x[:, 1], a[1] * x[:, 1], sep='\n')
4)奇异值分解
将矩阵M分解为U、S和V三个因子矩阵的乘积,即M=USV,其中U和V是正交矩阵,即UU^T=E、VV^T=E,S被称为M的奇异值矩阵,其非主对角线上的元素均为0,主对角线上的元素称为矩阵M的奇异值。
numpy.linalg.svd(M, full_matrices=False)
-> U, 奇异值, V
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import numpy as np
M = np.mat('4 11 14; 8 7 -2')
print(M)
U, s, V = np.linalg.svd(M, full_matrices=False)
print(U, s, V, sep='\n')
print(U * U.T, V * V.T, sep='\n')
S = np.diag(s)
print(S)
print(U * S * V)
5)行列式
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.linalg.det(A)->行列式的值
# -*- 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))
傅里叶定理:任何一个周期函数总可以被分解为若干不同振幅、频率和相位的正弦函数的叠加。
f(x) = 4/1pi sin(1x) + 4/3pi sin(3x) + 4/5pi sin(5x) +
4/7pi sin(7x) + ...
非周期函数可被视为周期无穷大的周期函数,傅里叶级数变成傅里叶积分。在工程上,从这些连续的频率中再选取离散的频率采样,得到离散化的频率序列,这就是离散傅里叶形式。
时间域的离散 -> 频率域的离散
x1->y1 f1 -> A1 fai1 A1sin(f12pi x+fai1)
x2->y2 f2 -> A2 fai2 A2sin(f22pi x+fai2)
... ...
xn->yn fn -> An fain Ansin(fn2pi x+fai2)
\_________FFT___________^ +)------------------------
y = f(x)
^_______________IFFT___________________/
import np.fft as nf
nf.fftfreq(时间域离散样本的个数,时间域离散样本的间隔)
采样周期=1/采样频率
->频率域的离散样本系列(f1,f2,...,fn),单位Hz
nf.fft([y1,y2,...,yn])->[(A1,fai1), (A2,fai2), ...]
\ /
a+bj
模正比A1
幅角就是fai1
nf.ifft([(A1,fai1), (A2,fai2), ...])->[y1,y2,...,yn]
# -*- 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) # 逆傅里叶变换:频率域->时间域
mp.figure('FFT', facecolor='lightgray')
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()
音频滤波
.wav文件记录一段声音在每一个采样时刻的位移,即位移关于时间的函数:s=f(t),以时间域的方式表现声音。
数学中的函数:y = 3x^2+2x+1
计算机中的函数:多个存在对应关系的数组
1 2 3 4 5 ...
6 17 34 57 86 ...
含有噪声的 FFT 含有噪声的 频率滤波 不含噪声的
时间域信号 -------> 频率域谱线 ----------> 频率域谱线
| IFFT
v
不含噪声的
时间域信号
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
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()
1)二项分布
np.random.binomial(n, p, size)
返回由size个随机数组成的数组,其中每个随机数来自n次尝试中成功次数,每次尝试成功的概率为p。
猜硬币游戏,初始筹码1000,每轮猜9次硬币,猜对5次及以上为赢,筹码加1,否则为输,筹码减1,进行10000轮,绘制手中筹码变化的曲线。
n=9
p=0.5
size=10000
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
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=10)
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.scatter(o, chips[o], edgecolor='deepskyblue',
facecolor='none', s=60,
label='Opening: %d' % chips[o], zorder=3)
mp.scatter(h, chips[h], edgecolor='crimson',
facecolor='none', s=60,
label='Highest: %d' % chips[h], zorder=3)
mp.scatter(l, chips[l], edgecolor='seagreen',
facecolor='none', s=60,
label='Lowest: %d' % chips[l], zorder=3)
mp.scatter(c, chips[c], edgecolor='orange',
facecolor='none', s=60,
label='Closing: %d' % chips[c], zorder=3)
mp.legend()
mp.show()
2)超几何分布
np.random.hypergeometric(ngood, nbad, nsample, size)
返回由size个随机数组成的数组,其中每个随机数来自随机抽取的nsample个样本中的好样本的个数,总样本空间由ngood个好样本和nbad个坏样本组成。
摸小球游戏,将25个红色小球和1个绿色小球放在一起,每轮摸出3个小球,若全是红色小球,加1分,否则扣6分,进行100轮,绘制分值的变化曲线。
ngood = 25
nbad = 1
nsample = 3
size = 100
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
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=10)
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.scatter(o, scores[o], edgecolor='deepskyblue',
facecolor='none', s=60,
label='Opening: %d' % scores[o], zorder=3)
mp.scatter(h, scores[h], edgecolor='crimson',
facecolor='none', s=60,
label='Highest: %d' % scores[h], zorder=3)
mp.scatter(l, scores[l], edgecolor='seagreen',
facecolor='none', s=60,
label='Lowest: %d' % scores[l], zorder=3)
mp.scatter(c, scores[c], edgecolor='orange',
facecolor='none', s=60,
label='Closing: %d' % scores[c], zorder=3)
mp.legend()
mp.show()
3)标准正态分布
平均值为0,标准差为1的正态分布
2
x
- ---
2
e
-------
-----
V 2pi
np.random.normal(平均值(0), 标准差(1), size=样本数)
->由size个服从标准正态分布的随机数组成的数组
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import numpy as np
import matplotlib.pyplot as mp
samples = np.random.normal(size=10000)
print(samples.mean(), samples.std())
x = np.linspace(samples.min(), samples.max(), 1000)
y = np.exp(-x**2 / 2) / np.sqrt(2 * np.pi)
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=10)
mp.grid(axis='y', linestyle=':')
mp.hist(samples, 100, normed=True,
edgecolor='steelblue', facecolor='deepskyblue',
label='Normal')
mp.plot(x, y, c='orangered', label='Probability')
mp.legend()
mp.show()
间接关联排序
间接排序:以样本下标而非样本本身来表示排序的结果。
0 1 2 3 4
原始样本:[10 40 30 50 20]
直接排序:[10 20 30 40 50]
间接排序:[ 0 4 2 1 3 ]
关联排序:对被排序序列中值相同的元素,参考另一个序列的升序条件决定其顺序。
0 1 2 3 4
待排序列:[10 40 30 40 20]
参考序列:[ B C A E C ]
排序序列:[ 0 4 2 1 3 ]
np.lexsort((参考序列, 待排序列))->有序下标
np.sort_complex(复数数组)->直接排序结果
按照实部的升序排列,若实部相同,参考虚部的升序
[1 2 4 5 6 8 9]<-[7 3]
np.searchsorted([1 2 4 5 6 8 9], [7 3])->插入位置
被插序列 插入序列
np.insert(被插序列, 插入位置, 插入序列)->插入结果
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import numpy as np
names = np.array(['zhangfei', 'zhaoyun', 'guanyu',
'huangzhong', 'machao'])
scores = np.array([90, 70, 60, 70, 90])
ages = np.array([50, 30, 20, 20, 40])
# 按照成績的升序打印姓名,成績相同的參考年齡的升序
print(names[np.lexsort((ages, scores))])
complexes = scores + ages * 1j
sorted_complexes = np.sort_complex(complexes)
print(complexes, sorted_complexes, sep='\n')
# 0 1 *2 3 4 *5 6
a = np.array([1, 2, 4, 5, 6, 8, 9])
print(a)
b = np.array([7, 3])
print(b)
c = np.searchsorted(a, b)
print(c)
# 将b数组中的元素按照c数组中的对应
# 位置插入a数组中,返回插入结果
d = np.insert(a, c, b)
print(d)
数组中的nan元素通常表示一个无效值,没有实际的数值语义,只是起到一个占位或者标志的作用。但在通过max/min/argmax/argmin获取数组元素的最大/最小值时,nan元素既被视为最大值也被视为最小值,除非使用nanmax/nanmin/nanargmax/nanargmin函数,以明确表示忽略数组中的所有nan值。
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import numpy as np
a = np.array([10, np.nan, 30, np.nan, 50])
print(a.shape, a.size, a.dtype, type(a[1]), a[1])
print(np.nan > 1000)
print(np.nan < 1000)
print(np.nan == 1000)
print(np.nan != 1000)
print(np.nan + 1000, np.nan - 1000)
# nan元素既是极大值也是极小值
print(np.max(a), np.min(a))
print(np.argmax(a), np.argmin(a))
# 忽略nan元素,获取极大/极小值
print(np.nanmax(a), np.nanmin(a))
print(np.nanargmax(a), np.nanargmin(a))
print(np.msort(a))
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
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元,
# 到期后本息合计1561.11?
pv = np.pv(0.01, 5, -100, 1561.11)
print(round(pv, 2))
# 净现值 = 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, -1485.34)
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(round(npv, 2))
# 每期支付 = pmt(利率, 期数, 现值)
# 以1%的年利率从银行贷款1000元,分5年还清,
# 每年还多少钱?
pmt = np.pmt(0.01, 5, 1000)
print(round(pmt, 2))
# 期数 = nper(利率, 每期支付, 现值)
# 以1%的年利率从银行贷款1000元,平均每年还款206.04元,
# 多少年还清全部本息?
nper = np.nper(0.01, -206.04, 1000)
print(np.round(nper))
# 利率 = rate(期数, 每期支付, 现值, 终值)
# 从银行贷款1000元,平均每年还款206.04元,
# 5年还清全部本息,年利率多少?
rate = np.rate(5, -206.04, 1000, 0)
print(round(rate, 2))
import scipy.integrate as si
si.quad(积分函数, 积分下限, 积分上限)
->积分函数在[积分下限,积分上限]区间的定积分
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import numpy as np
import scipy.integrate as si
import matplotlib.pyplot as mp
import matplotlib.patches as mc
def f(x):
y = 2 * x ** 2 + 3 * x + 4
return y
a, b = -5, 5
x1 = np.linspace(a, b, 1001)
y1 = f(x1)
n = 50
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)
area = si.quad(f, a, b)[0]
print(area)
mp.figure('Area', facecolor='lightgray')
mp.title('Area', 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()
想要看更多的课程请微信关注SkrEric的编程课堂