day06-矩阵-矢量函数转换-加法、除法、取余通用函数-三角函数-线性代数-傅里叶变换
19、矩阵
1、numpy.matrix 继承自 numpy.ndarray
任何针对多维数值的操作,对矩阵同样有效,
但作为子类矩阵又结合自身的特点,做了必要的
扩充,比如:乘法、求逆
2、矩阵对象三种创建方式:
1、numpy.matrix(任何被解释为矩阵的二维容器,
copy=是否复制(默认为True))
返回矩阵对象
copy = False, 所得矩阵与源容器共享一份数据
copy = True,所得矩阵各自独立数据
2、numpy.mat(...) <==> numpy.matrix (..., copy=False
mat不同于matrix之处在于其只能获取已有矩阵视图,
而无法得到拷贝。
3、numpy.bmat(拼块规则)
函数可以将已定义的矩阵逐块拼接。
将小块矩阵拼接为大块矩阵
拼接块的维度必须相同
以上三个都可接受字符串形式的矩阵描述,即:
数据项用空格分隔,数据行用分号分隔。
|1 2 3|
例如:'1 2 3; 4 5 6;7 8 9'<==> |4 5 6|
|7 8 9|
数组相乘:对应元素相乘
矩阵相乘:Amp * Bpn = Cmn
计算第C[m,n]位置的元素值为:
[Am行]*[Bn列]对应元素相乘后之和
如:求C[2,3]元素的值,则为
A第2行 乘以 B第3列 后的值
求逆矩阵:矩阵.I
代码:mat.py
示例:
import numpy as np
a = np.array([[1,2,6],
[3,5,7],
[4,8,9]])
b = np.matrix(a)
c = np.mat('1 4 7;2 5 8;3 6 9')
d = np.bmat('c b')
print(np.bmat('c b ; b c'))
print(a * b)
print(b.I)
20.通用函数
1、frompyfunc转为矢量函数
numpy.frompyfunc(标量函数,参数个数,返回值个数)
转为矢量函数
与17、矢量函数 基本一致:numpy.vectorize(标量函数)(矢量)
frompyfunc与vectorize比,比较早期应用。
2.加法的通用函数add
numpy.add.reduce() - 累加
numpy.add.accumulate - 累加过程
numpy.add.reduceat - 分段累加
numpy.add.outer - 外和
注意:numpy.outer - 外积
代码:add.py
示例:
import numpy as np
a = np.arange(1,7)
print(a)
b = np.add(a,a) # <==> a + a
print(np.add.reduce(a)) # 输出:21
print(np.add.accumulate(a)) #每次累加的过程:[ 1 3 6 10 15 21]
#按a的下标分为三段累加:第一段:a[0]及后面;第二段:a[2]及后面;第三段:a[4]及以后
print(np.add.reduceat(a,[0,2,4]))#分段累加,输出:[3 7 11]
#以下外和,输出:
#[11 12 13 14 15 16]
#[21 22 23 24 25 26]
#[31 32 33 34 35 36]]
print(np.add.outer([10,20,30],a))#外和
print(np.outer([10,20,30],a)) #外积
3.除法的通用函数
1)真除:numpy.divide、true_divide、/
无论运算数是整型还是浮点,运算结果都是浮点数,
保留小数。
2)地板除(向下去整):floor_divide、//
运算数是整型,运算结果也是整型,运算数是浮点,
运算结果也是浮点,向下去整。
3)天花板取整
numpy.ceil()
4)天花板除
先真除,然后天花板取整
numpy.ceil(numpy.divide(a))
5)截断取整
numpy.trunc()
6)截断除,也就是取整除
先真除,然后截断取整
numpy.trunc(numpy.divide(a))
示例:
import numpy as np
a = np.array([5,5,-5,-5])
b = np.array([2,-2,2,-2])
print(np.true_divide(a,b)) #真除 输出:[ 2.5 -2.5 -2.5 2.5]
print(np.divide(a,b)) #真除 输出:[ 2.5 -2.5 -2.5 2.5]
print(a / b) #真除 输出:[ 2.5 -2.5 -2.5 2.5]
print(np.floor_divide(a,b)) #地板除 输出:[ 2 -3 -3 2]
print(a // b) #地板除 输出:[ 2 -3 -3 2]
print(np.ceil(a/b)) #天花板取整 输出:[ 3. -2. -2. 3.]
print(np.trunc(a / b)) #截断取整 输出:[ 2. -2. -2. 2.]
4.取余的通用函数
1)取余numpy.remainder
2)取模numpy.mod
3)python取模: %
4)获得截断除的模numpy.fmod
示例:
import numpy as np
a = np.array([5,5,-5,-5])
b = np.array([2,-2,2,-2])
print(np.remainder(a , b)) #取余,输出:[ 1 -1 1 -1]
print(np.mod(a,b)) #取余,输出:[ 1 -1 1 -1]
print(a % b) #取余,输出:[ 1 -1 1 -1]
print(np.fmod(a , b)) #截断除后取余,输出:[ 1 1 -1 -1]
5.Numpy将Python语言中针对标量的运算符,
通过通用函数加以重载定义,以支持数组的矢量运算。
斐波那契数列
1 1 2 3 5 8 13 ...
Fn = Fn-1 + Fn-2, n>=3
示例:
import numpy as np
n = 35
#方法一:递归
def fibo(n):
return 1 if n<3 else fibo(n-1) + fibo(n-2)
#方法二:循环
def fiboFor(n):
fn1,fn2=0,1
for i in range(n):
fn = fn1 + fn2
fn1,fn2 = fn,fn1
return int(fn)
#方法三:numpy矩阵
def fiboNumpy(n):
E = np.mat('1. 1. ; 1. 0.')
fibo = int((E ** (n-1))[0,0])
return fibo
#方法四:公式法
def fibogs(n):
r = np.sqrt(5)
return int((((1+r)/2) ** n - ((1-r)/2) ** n) / r)
print(fibogs(n))
print(fiboNumpy(n))
print(fiboFor(n))
print(fibo(n))
6.三角函数
在numpy中所有的标准三角函数都是通用函数,
可对数组或矩阵中的每个元素求取其三角函数的值,
构成值数组或值矩阵。
李萨如曲线:
x = Asin(at+pi/2) A:正负,a:角频率, 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,1,5,2
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()
信号发生器方波:若干不同频率的正玄波叠加,就会形成方波
y1 = 4/pi * sin(x)
y2 = 4/(3pi) * sin(3x)
yn...4/(奇数pi) * sin(奇数x)
y1+y2+..+yn
将方波分解成正弦波,三角波等,叫:傅里叶分解
是信号发生器方波的逆运算
示例:
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,y4,label='n=10')
# mp.plot(x,y5,label='n=100')
mp.plot(x,y6,label='n=1000')
mp.legend()
mp.show()
7.位运算
1)异或:^/__xor__/bitwise_xor
1^0=1
1^1=0
0^0=0
0^1=1
相异取真, 相同得假
如判断a b是否正负异号:
方法之一:a * b < 0 ,则a与b异号
方法之二:a ^ b < 0 , 则a与b异号,
这样的效率比方法一高
示例:
import numpy as np
a = np.array([0,-1,2,-3,4,-5])
b = np.array([0,1,2,3,4,5])
c = a ^ b
print (c)
print(np.where(c < 0)[0])
2)与:& / __and__ / bitwise_and
1&0=0
1&1=1
0&0=0
0&1=0
都为真时,才是真
如果一个整数n和n-1位进行"与"运算的结果为0,
则n一定是2的整数次幂。
即:n & (n-1) = 0 ,则n是2的幂
示例:
d = np.arange(1,20)
e = d & (d -1)
print(e)
print(d[e == 0])
3)或:| / or / bitwise_or
只要有一个为真,即为真
4)取反: ~ / __not__ / bitwise_not
5)移位:
左移位:<< / __lshift__ / bitwise_left
左移一位,则乘2,移多位,则为乘2的n次方
右移为:>> /__rshift__ / bitwise_right
右移一位,则除2,移多位,则为除以2的n次方
五、numpy的模块
1.线性代数模块(linalg)
1)矩阵求逆:inv
在线性代数中,
矩阵A与矩阵B的乘积是一个单位矩阵E,
那么A和B互为逆矩阵,即为:
AxB=E ==> A^-1 = B
B = numpy.linalg.inv(A)
将以上定义推广到非方阵,则称为广义逆矩阵
np.linalg.pinv(A) --> A^-1
np.matrix.I(A)-->如果A是方阵,则可用inv
如果非方阵,则可用pinv
示例:
import numpy as np
A = np.mat('1 2 3;8 9 4;7 6 5')
B = np.linalg.inv(A) #A的逆矩阵
print(B)
print(A.I)#A的逆矩阵
c = np.mat('11 12 13 14;20 21 22 15;19 18 17 16')
print(c)
d = np.linalg.pinv(c)#广义逆矩阵
print(d)
print(c * d)
print(c.I)
2)解线性方程组
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 | * | y | = | 8 |
|-4 5 9 | | z | | -9 |
A x B
方法一:拟合方法
x = nump.linalg.lstsq(A,B)[0]
未知数少于方程数时,会求近似值
方法二:解方程
x = numpy.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')
x1 = np.linalg.solve(A,B)
x2 = np.linalg.lstsq(A,B)[0]
print(x1)
print(x2)
3)特征向量和特征值
对于n阶方阵A,如果存在数a和非零n维列向量x,
使得Ax=ax成立,则称a是矩阵A的一个特征值,
x是矩阵A属于特征值a的特征向量。
numpy.linalg.eigvals(A) ==> 输出特征值
numpy.linalg.eig(A) ==> 可得出a 和 x,
即特征数组和特征向量数组
[ a1 a2]
[x11 x12]
[x21 x22]
示例:
import numpy as np
A = np.mat('3 -2;1 0')
eigvals,eigvecs = np.linalg.eig(A) #输出特征值和特征向量
print(eigvals) #输出特征值
print(eigvecs) #输出特征向量
print(A * eigvecs[:,0]) # 即概念中的A*x
print(eigvals[0]*eigvecs[:,0]) #即概念中的ax
#即:A*x = a*x
4)奇异分解(矩阵中的因式分解)
若:M=U * S * V,
其中U和V是正交矩阵,即U*U.T=E=V*V.T,
U.T,V.T为转置矩阵, E是单位矩阵
S被称为M的奇异值矩阵。
U, s, V = numpy.linalg.svd(M,full_matrices=False)
full_matrices是否填充,False表示自然状态,不填充
其中的s只是奇异值矩阵的主对角线,
S=numpy.diag(s) 获得奇异值
应用场景:人脸识别,要忽略细微差异,
获得关键因素,要降低维度
代码:usv.py
示例:
import numpy as np
M = np.mat('4 11 14;8 7 -2')
U , s, V = np.linalg.svd(M, full_matrices=False)
print(U * U.T)
print(s) #输出奇异值对角线
print(V * V.T)
S = np.diag(s)
print(S)#输出奇异值
print(U * S * V)
6)行列式的值
| a b | = ad - bc
| c d |
| a b c | = a |e f| - b |d f| + c |d e|
| d e f | |h i| |g i| |g h|
| g h i | a的(余子式) b的(余子式) c的(余子式)
=a(ei-fh)-b(di-fg)+c(dh-eg)
=aei-afh-bdi+bfg+cdh-ceg
numpy.linalg.det(矩阵) -> 行列式值
示例:
import numpy as np
A = np.mat('2 1;3 4')
print(np.linalg.det(A))
B = np.mat('3 2 1;4 9 8;5 6 7')
print(np.linalg.det(B))
2.快速傅立叶变换(Fast Fourier Transform, FFT)
傅立叶定理:任何一个函数,都可以分解为一系列正玄函数的叠加
即:原函数:y = f(x) ,也叫时空域函数
可分解为:一系列正玄函数的叠加,
只是这些正玄函数的角频率ω,相位φ
y=A1sin(ω1x+φ1)+A2sin(ω2x+φ2)+ ...+
Ansin(ωnx+φn)+ R
当n-> ∞ 时,R 会逼近于0
意义:将一个复杂函数用无数个简单函数(sin函数)表示
快速傅里叶:
通过已知的样本,[x1,x2,...,xn] [y1,y2,...,yn],即离散的样本值
获得离散傅里叶,再进行优化,就成了快速傅里叶
ω1 --> A1,φ1 \
ω2 --> A2,φ2 | 即转为:A,φ = f(ω) 频率域函数
... | A是振幅, φ是初相位,ω是频率
ωn --> An,φn /
即:傅立叶变换实际就是:将时空域函数转变为频率域函数,是一个分解过程
傅里叶逆变换就是:将频率域函数转变为时空域函数,是一个合成的过程
numpy.fft.fftfreq(样本数n, 采样周期dt) --> 输出频率序列ω
numpy.fft.fft(原函数序列f) --> 获得目标函数值序列,是一个复数序列
复数的模反映了振幅A,辐角反映了初相位φ
即:傅里叶变换
numpy.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 #real,要实部
mp.figure('快速傅里叶变换',facecolor='lightgray')
mp.subplot(121)
mp.title('TimeDomain',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',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],label='Frequency')
mp.legend()
mp.tight_layout()
mp.show()
代码:fourier.py
逆向傅立叶变换
低频信号<------------------------------------------------低
| 叠加 傅立叶变换 低通滤波 频
+----> 含噪信号 ------------> 含噪频谱 ---------->频
| 谱
高频噪声
代码:filter.py
fftfreq/fft : 0 1 2 3 ... 1000 -1000 ... -3 -2 -1 0
由numpy.fft.fftfreq/numpy.fft.fft函数返回的频谱数组,按照从0到+max再从-max到0的顺序排列,
通过numpy.fft.fftshift函数做移频操作,可将其变为-max到+max的排列顺序,
numpy.fft.ifftshift可完成相反的移频操作。
day07---------------------------------------------------
基于傅里叶变换的频域滤波:
______________________________________
| IFFT |
V |
高能信号\ |
|>含噪信号---->含噪频谱-------->高能频谱
低能噪声/ FFT 频域滤波
numpy.fft.FFT(原函数序列f):傅里叶变换
numpy.fft.IFFT():傅里叶逆变换
numpy.fft.fftfreq(样本数量,采样周期):
获得频谱数组,从0到+max再从-max到0排列
numpy.fft.fftshift:移频操作,变为-max到+max顺序
numpy.fft.ifftshift:与fftshift相反的移频操作。
代码:filter.py
示例(音频去噪):
import numpy as np
import numpy.fft as nf
import matplotlib.pyplot as mp
import scipy.io.wavfile as wf #scipy主要用于多媒体处理
#sample_rate,采样率,noised_sigs信号
sample_rate,noised_sigs = wf.read('./noised.wav')
#print(sample_rate) #输出44100,表示每秒钟采样的数量
#noised_sigs.shape为样本总数,将总数除以采样率,就是时间
#print(noised_sigs.shape)#输出格式:(声道1总数,声道2总数,声道3总数,声道4总数,..)
#dtype输出int16,数据实际为浮点数,该模块处理为:int16(数据*2**15),使用时需要还原
#print(noised_sigs.dtype)
noised_sigs = noised_sigs / 2**15 #数据还原
times = np.arange(len(noised_sigs))/sample_rate #获得采样点时间
#获得频谱数组,代表能量强度
freqs = nf.fftfreq(times.size,1/sample_rate) #sample_rate采样频率的倒数即为采样周期
#print(times.size,noised_sigs.shape) #times.size也是样本总数
noised_ffts = nf.fft(noised_sigs)#进行傅里叶变换,获得复数形式的离散函数组
noised_pows =np.abs(noised_ffts) #对复数取模,获得能量值
#开始滤波
pow_max = noised_pows.argmax() #获得最大值下标
fund_freq = np.abs(freqs[pow_max])#获得能量最大值对应的频率,基频
#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
#将去噪后的信号保存为文件,样本数不变,转换数据类型为int16
wf.write('./filter.wav',sample_rate,
(filter_sigs * 2 ** 15).astype(np.int16))
mp.figure('filter',facecolor='lightgray')
mp.subplot(221)
mp.title('timeDoDomain',fontsize=16)
mp.ylabel('Sigal',fontsize=12)
mp.tick_params(labelsize=10)
mp.grid(linestyle=':')
mp.plot(times[:178],noised_sigs[:178],label='Noised')
mp.legend()
mp.subplot(222)
mp.ylabel('Power',fontsize=12)
mp.tick_params(labelsize=10)
mp.grid(linestyle=':')
#用plot直接按以下这样显示,差别太大,看不出区别,可用半对数坐标方式显示
#mp.plot(freqs[freqs>=0],noised_pows[freqs>=0],label='Freqs')
#semilogy半对数坐标
mp.semilogy(freqs[freqs>=0],noised_pows[freqs>=0],label='noised')
#通过以上观察可发现:低能频谱基本在10**3以下
mp.legend()
mp.subplot(223)#绘制去噪后的时空域函数曲线
mp.title('timeDoDomain',fontsize=16)
mp.xlabel('time',fontsize=12)
mp.ylabel('Sigal',fontsize=12)
mp.tick_params(labelsize=10)
mp.grid(linestyle=':')
mp.plot(times[:178],filter_sigs[:178],label='filter_sigs')
mp.legend()
mp.subplot(224)#绘制去噪后的能量曲线
mp.xlabel('frequercy',fontsize=12)
mp.ylabel('Power',fontsize=12)
mp.tick_params(labelsize=10)
mp.grid(linestyle=':')
mp.plot(freqs[freqs>=0],filter_pows[freqs>=0],label='filter')
mp.legend()
mp.tight_layout()
mp.show()
day07-随机数-超几何分布-标准正态分布-排序-插值-积分-图像处理-金融计算
3.随机数(random)
生成服从特定统计规律的随机数序列
统计规律如:正态、均匀、离散分布规律等等
1)二项分布
numpy.random.binomial (n, p, size) -> [size个随机数]
size:产生随机个数,
n:尝试次数
p:成功的概率
如猜硬币的游戏:初始筹码1000,每轮猜9次,猜对5次
或5次以上为赢,筹码加1,否则为输,筹码减1。
求:10000轮的过程中手中筹码的变化。
binomial(9, 0.5 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)
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.figure('bi',facecolor='lightgray')
mp.title('bi',fontsize=20)
mp.xlabel('Round',fontsize=14)
mp.ylabel('chip',fontsize=14)
mp.tick_params(labelsize=10)
mp.grid(linestyle=':')
mp.plot(chips,c=color,label='bi')
mp.axhline(y=chips[o],linestyle = '--',linewidth = 1,color = 'deepskyblue')
mp.axhline(y=chips[h],linestyle = '--',linewidth = 1,color = 'crimson')
mp.axhline(y=chips[l],linestyle = '--',linewidth = 1,color = 'seagreen')
mp.axhline(y=chips[c],linestyle = '--',linewidth = 1,color = 'orange')
mp.legend()
mp.tight_layout()
mp.show()
2)超几何分布
numpy.random.hypergeometric(ngood, nbad,
nsample, size)
size:产生的随机次数
nsample:随机抽取好样本的个数
nbad:总样本中坏样本的个数
ngood:总样本中好样本的个数
产生size个随机数,
每个随机数来自随机抽取的nsample个样本中好样本个数,
总体样本有ngood个好样本和nbad个坏样本组成。
模球游戏:
25个好球和1个坏球放在一起,
每次摸3个球,全为好球加1分,摸到坏球减6分
求100轮过程中分值的变化
np.random.hypergeometric(25,1,3,100)
示例:
import numpy as np
import matplotlib.pyplot as mp
outcomes = np.random.hypergeometric(25,1,3,100)
#print(outcomes)
scores = [0]
for outcome in outcomes:
if outcome == 3:
scores.append(scores[-1]+1)
else:
scores.append(scores[-1]-6)
scores = np.array(scores)
#print(scores)
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.figure('hypergeometric',facecolor='lightgray')
mp.title('bi',fontsize=20)
mp.xlabel('Round',fontsize=14)
mp.ylabel('scores',fontsize=14)
mp.tick_params(labelsize=10)
mp.grid(linestyle=':')
mp.plot(scores,c=color,label='scores')
mp.axhline(y=scores[o],linestyle = '--',linewidth = 1,color = 'deepskyblue')
mp.axhline(y=scores[h],linestyle = '--',linewidth = 1,color = 'crimson')
mp.axhline(y=scores[l],linestyle = '--',linewidth = 1,color = 'seagreen')
mp.axhline(y=scores[c],linestyle = '--',linewidth = 1,color = 'orange')
mp.legend()
mp.tight_layout()
mp.show()
3)标准正态分布
numpy.random.normal(size)
产生size个随机数,服从标准正态(平均值0,标准差1)分布。
正态分布函数概率密度: e^((-x^2)/2)/√2π
见:正态分布函数.png
代码:normal.py
示例,正态分布直方图:
import numpy as np
import matplotlib.pyplot as mp
samples = np.random.normal(size=1000)
mp.figure('Normal',facecolor='lightgray')
mp.title('Normal',fontsize=20)
mp.xlabel('Sample',fontsize=14)
mp.ylabel('Occ',fontsize=14)#出现的机会
mp.tick_params(labelsize=10)
mp.grid(axis='y',linestyle=':')
#画直方图,将样本分成100份(100个直方条)
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.tight_layout()
mp.show()
六、numpy的其他函数
1.排序和查找
1)联合间接排序:
numpy.lexsort((参考序列,待排序列)) -->返回有序的索引
例如:numpy.lexsort((年龄,成绩))
--->获得成绩排名,
之后可根据成绩排名获得对应的姓名
首先按成绩排序,相同成绩的,按照年龄排序
相当于是:首要排序成绩,次要排序年龄
返回a数组按升序排列的索引数组,
对于a数组中值相同的元素参考其在b数组中对应元素的升序排列。
示例:
ages = np.array([30,20,30,20])
scores = np.array([70,60,80,70])
names = np.array(['zhang','li','wang','zhao'])
#先按scores排序,然后按ages排序
l=np.lexsort((ages,scores))
print(l)
name = np.take(names,l)
print(name) #输出对应排序的姓名
2)sort_complex(复数数组)
按照复数实部的升序排序,
对于实部相同的元素参考其虚部的升序。
示例:
ages = np.array([30,20,30,20])
scores = np.array([70,60,80,70])
names = np.array(['zhang','li','wang','zhao'])
complexes = scores + ages * 1j#创建复数数组
print(np.sort_complex(complexes))#对复数排序
3)argmax/argmin/max/min: 将nan值视为最大和最小值
4)nanargmax/nanargmin/nanmax/nanmin: 将nan值直接忽略不计
5)有序插入:searchsorted / insert
searchsorted(有序序列,待查序列)
将待插序列插入有序序列后,结果依然有序
返回分别应该放在哪个位置的数组
有序插入: insert(被插序列,位置序列,待插序列)
将待插序列按照位置序列插入被插序列,并返回
示例:
a = np.array([1,2,4,5,6,8,9])
b = np.array([7,3])
c = np.searchsorted(a,b) #获得位置数组
d = np.insert(a,c,b)#将b按照c的位置插入到a中
print(d)
6)where/掩码/extract/nonzero: 根据条件选择元素
2.插值
收集到的有限样本数据,很难形成曲线,
通过插值方式,插入多个模拟数据,最终形成近似接近的曲线
import scipy.interpolate as si
一维插值si.interp1d(离散x坐标,离散y坐标,
kind=插值算法(默认为线性插值)) -->返回茶之器
插值器(x坐标)-->得出y坐标
二维插值si.interp2d
三维插值si.interp3d
示例:
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) # 比dis_x多了40个,则多余的就需要插值去完成
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('interpolate',facecolor='lightgray')
mp.subplot(221)
mp.title('interpolate',fontsize=16)
mp.xlabel('x',fontsize=12)
mp.ylabel('y',fontsize=12)
mp.tick_params(labelsize=10)
mp.grid(linestyle=':')
mp.plot(con_x,con_y,c='hotpink',label='Cont')
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=60,label='dis')
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-',label='linear')
mp.scatter(dis_x,dis_y,c='orangered',s=60,zorder=3)
mp.subplot(224)
mp.title('Cubic',fontsize=16)
mp.xlabel('X',fontsize=12)
mp.ylabel('Y',fontsize=12)
mp.tick_params(labelsize=10)
mp.grid(linestyle=':')
#绘制插值后的曲线
mp.plot(cub_x,cub_y,'o-',label='cubic')
mp.scatter(dis_x,dis_y,c='orangered',s=60,zorder=3)
mp.legend()
mp.tight_layout()
mp.show()
3.积分
import matplotlib.pyplot as mp #用于绘制曲线,散点等
import matplotlib.patches as mc #用于绘制几何图形,如三角,园等
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 #一个典型的二次多项式 ,抛物线
a , b = -5,5
#按scipy计算积分
area1 = si.quad(f,a,b)
print(area1)
#按照古典方式计算积分
n = 300
x2 = np.linspace(a,b,n+1)
y2 = f(x2)
area = 0
for i in range(n):
#梯形面积公式:(上底 + 下底)* 高 / 2
area += (y2[i] + y2[i+1]) * (x2[i+1]-x2[i]) / 2
print(area)
mp.figure('Integral',facecolor='lightgray')
mp.title('Integral',fontsize=16)
mp.xlabel('x',fontsize=12)
mp.ylabel('y',fontsize=12)
mp.tick_params(labelsize=10)
mp.grid(linestyle=':')
#绘制曲线
x1 = np.linspace(a , b, 1001)
y1 = f(x1)
mp.plot(x1,y1,label=r'$y=2x^2+3x+4$')
#绘制古典积分方法用的多边形
for i in range(n):
mco = 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.gca().add_patch(mco)
mp.legend()
mp.tight_layout()
mp.show()
4.图像
import scipy.ndimage as sn #可进行颜色变换
import scipy.misc as sm
#相对scipy,opencv的图像处理更强大
#pip install opencv-python
示例:
import scipy.misc as sm
import scipy.ndimage as sn #可进行颜色变换
import matplotlib.pyplot as mp
originalt = sm.imread('./lily.jpg')#读取图片的源格式
#print(originalt.shape,originalt.dtype) #(512, 512, 3) 表示(高度,宽度,颜色通道) 3,表示红绿蓝
original = sm.imread('./lily.jpg',True)#读取图片的灰度格式
#print(original.shape,original.dtype) #(512, 512) float32,没有颜色维了
median = sn.median_filter(original,(20,20))#中值滤波,实际是二维卷积模糊化,也叫高斯模糊
#卷积模糊通常用于去除杂质
rotate = sn.rotate(originalt,45) #旋转45度
prewitt = sn.prewitt(original)#索贝尔边缘识别,索贝尔微分,浮雕效果,找物体轮廓
mp.figure('Image',facecolor='lightgray')
mp.subplot(221)
mp.title('Original',fontsize=16)
mp.axis('off')
mp.imshow(original,cmap='gray')
mp.subplot(222)
mp.title('prewitt',fontsize=16)
mp.axis('off')
mp.imshow(prewitt)
mp.subplot(223)
mp.title('mediane',fontsize=16)
mp.axis('off')
mp.imshow(median,cmap='gray')
mp.subplot(224)
mp.title('rotate',fontsize=16)
mp.axis('off')
mp.imshow(rotate,cmap='gray')
mp.tight_layout()
mp.show()
5.金融计算
1)终值fv(利率,期数,每期支付,现值)
如:将1000元存入银行,利率为1%,存5年,每年加存100
到期后本息合计多少
np.fv(0.01,5,-100,-1000) #资金流出为负,流入为正
示例:
fv = np.fv(0.01,5,-100,-1000)
print(round(fv,2)) #输出:1561.11
2)现值pv(利率,期数,每期支付,终值)
如:银行利率为1%,存5年,每年加存100
到期后能拿到2000元,请问现在应该存多少
np.pv(0.01,5,-100,2000)
示例:
pv = np.pv(0.01,5,-100,2000)
print(round(pv,2)) #输出:-1417.59
3)净现值npv(利率,现金流)
如:将1000元存入银行,利率为1%,存5年,每年加存100
相当于现在一次性存入多少
npv(0.01,[-1000,-100,-100,-100,-100,-100])
示例:
npv = np.npv(0.01,[-1000,-100,-100,-100,-100,-100])
print(round(npv,2))#输出:-1485.34-
4)内部收益率IRR(现金流)
如:将1000元存入银行存5年,以后逐年提取100,200,300,400,
500,之后银行利率达到多少,可在最后一次体现尝清本息
即净现值为0
irr([-1000,100,200,300,400,500])
示例:
irr = np.irr([-1000,100,200,300,400,500])
print(round(irr,2))#输出:0.12
5)每期支付pmt(利率,期数,现值)
如:以1%的年利率从银行贷款1万,分5年还清,
平均每年还多少钱
pmt(0.01,5,10000)
示例:
pmt = np.pmt(0.01,5,10000)
print(round(pmt,2))#输出:-2060.4
6)还款期数nper(利率,每期支付,现值)
如:以1%的年利率从银行贷款1万,平均每年还2060.4
多少年还清,
nper(0.01,-2060.4,10000)
示例:
nper = np.nper(0.01,-2060.4, 10000)
print(nper)#输出:约5
7)贷款利率rate(期数,每期支付,现值,终值)
示例:
rate = np.rate(5,-2060.4,10000,0)
print(rate)#输出:0.01
6.窗函数
1)巴特莱特窗:numpy.bartlett
2)布莱克曼窗:numpy.blackman
3)哈明窗:numpy.hamming
4)汉宁窗:numpy.hanning
5)凯瑟窗:numpy.kaiser