python DataScience数据分析笔记day06

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

猜你喜欢

转载自blog.csdn.net/pinecn/article/details/89738806