zoukankan      html  css  js  c++  java
  • Python 小波包变换,小波包能量特征提取 代码

    1. 小波外部包下载

    要下载两个包:

    PyWavelets和Matplotlib(要运行PyWavelets的所有测试,您还需要安装 Matplotlib软件包。)

    安装方法:

    pip install PyWavelets
    pip install Matplotlib

    相关链接:

    PyWavelets官网:里面有很多的API文档,有小波(小波家族,内置小波等),离散小波变换,逆小波变换等等

    小波包的相关用法实例

    2. 小波包的使用

    2.1 导入相关的包

    下面的导入的包中主要是pywt和matplotlib

    import numpy as np
    import matplotlib.pyplot as plt
    import os
    from sklearn import preprocessing
    import pywt
    import pywt.data
    import pandas as pd

    2.2  小波包各节点按照频率由低到高

    wp = pywt.WaveletPacket(data=tr, wavelet='db1',mode='symmetric',maxlevel=3)
    #根据频段频率(freq)进行排序
    print([node.path for node in wp.get_level(1, 'freq')])
    print([node.path for node in wp.get_level(2, 'freq')])
    print([node.path for node in wp.get_level(3, 'freq')])

       代码中tr表示输入的一维数据,执行结果如下

    ['a', 'd']
    ['aa', 'ad', 'dd', 'da']
    ['aaa', 'aad', 'add', 'ada', 'dda', 'ddd', 'dad', 'daa']

     2.3 打印小波家族

    pywt.families()
    #pywt.families(short=False)

      执行结果如下:

    ['haar', 'db', 'sym', 'coif', 'bior', 'rbio', 'dmey', 'gaus', 'mexh', 'morl', 'cgau', 'shan', 'fbsp', 'cmor']

     2.4 小波包的分解

      (1)小波包分解中关键方法:

    wp = pywt.WaveletPacket(data=tr, wavelet='db1',mode='symmetric',maxlevel=3)

        该方法输入原始信号tr, 小波函数'db1',模式'symmetric',以及最大的分解层数为3。返回wp是小波包树,根据小波包树我们可以提取分解系数。

       (2)提取分解系数:

         下面aaa是小波包变换第三层第一个的分解系数

    aaa = wp['aaa'].data 

          所以可以使用下面的方法提取每一层的每个节点的小波系数,当然这个方法不太方便,需要一个一个的写,后面有更好的方法:

    a = wp['a'].data #第1个节点
    d = wp['d'].data #第2个节点
    #第二层
    aa = wp['aa'].data 
    ad = wp['ad'].data 
    dd = wp['dd'].data 
    da = wp['da'].data 
    #第三层
    aaa = wp['aaa'].data 
    aad = wp['aad'].data 
    ada = wp['add'].data 
    add = wp['ada'].data 
    daa = wp['dda'].data 
    dad = wp['ddd'].data 
    dda = wp['dad'].data 
    ddd = wp['daa'].data

       (3) 作小波树图,下面代码中没有优化,后面做了优化:

    plt.figure(figsize=(15, 10))
     
    plt.subplot(4,1,1)
    plt.plot(tr)
    #第一层
    plt.subplot(4,2,3)
    plt.plot(a)
    plt.subplot(4,2,4)
    plt.plot(d)
    #第二层
    plt.subplot(4,4,9)
    plt.plot(aa)
    plt.subplot(4,4,10)
    plt.plot(ad)
    plt.subplot(4,4,11)
    plt.plot(dd)
    plt.subplot(4,4,12)
    plt.plot(da)
    #第三层
    plt.subplot(4,8,25)
    plt.plot(aaa)
    plt.subplot(4,8,26)
    plt.plot(aad)
    plt.subplot(4,8,27)
    plt.plot(add)
    plt.subplot(4,8,28)
    plt.plot(ada)
    plt.subplot(4,8,29)
    plt.plot(dda)
    plt.subplot(4,8,30)
    plt.plot(ddd)
    plt.subplot(4,8,31)
    plt.plot(dad)
    plt.subplot(4,8,32)
    plt.plot(daa)

       下图中使用的是心电信号,需要注意的是有些图形的刻度值太长嵌入了图中,结果图: 

     

        (4) 代码优化,使用的wpd_plt(signal,n)将上面的代码优化和封装了,signal代表输入信号,n代表分解层数:

    def wpd_plt(signal,n):
        #wpd分解
        wp = pywt.WaveletPacket(data=signal, wavelet='db1',mode='symmetric',maxlevel=n)
     
        #计算每一个节点的系数,存在map中,key为'aa'等,value为列表
        map = {}
        map[1] = signal
        for row in range(1,n+1):
            lev = []
            for i in [node.path for node in wp.get_level(row, 'freq')]:
                map[i] = wp[i].data
     
        #作图
        plt.figure(figsize=(15, 10))
        plt.subplot(n+1,1,1) #绘制第一个图
        plt.plot(map[1])
        for i in range(2,n+2):
            level_num = pow(2,i-1)  #从第二行图开始,计算上一行图的2的幂次方
            #获取每一层分解的node:比如第三层['aaa', 'aad', 'add', 'ada', 'dda', 'ddd', 'dad', 'daa']
            re = [node.path for node in wp.get_level(i-1, 'freq')]  
            for j in range(1,level_num+1):
                plt.subplot(n+1,level_num,level_num*(i-1)+j)
                plt.plot(map[re[j-1]]) #列表从0开始 

       2.5 小波包能量特征提取

    n = 3
    re = []  #第n层所有节点的分解系数
    for i in [node.path for node in wp.get_level(n, 'freq')]:
        re.append(wp[i].data)
    #第n层能量特征
    energy = []
    for i in re:
        energy.append(pow(np.linalg.norm(i,ord=None),2))
    #for i in energy:
    #    print(i)

         绘制小波能量特征柱形图,注意这里的节点顺序不是自然分解的顺序,而是频率由低到高的顺序:

    # 创建一个点数为 8 x 6 的窗口, 并设置分辨率为 80像素/每英寸
    plt.figure(figsize=(10, 7), dpi=80)
    # 再创建一个规格为 1 x 1 的子图
    # plt.subplot(1, 1, 1)
    # 柱子总数
    N = 8
    values = energy
    # 包含每个柱子下标的序列
    index = np.arange(N)
    # 柱子的宽度
    width = 0.45
    # 绘制柱状图, 每根柱子的颜色为紫罗兰色
    p2 = plt.bar(index, values, width, label="num", color="#87CEFA")
    # 设置横轴标签
    plt.xlabel('clusters')
    # 设置纵轴标签
    plt.ylabel('number of reviews')
    # 添加标题
    plt.title('Cluster Distribution')
    # 添加纵横轴的刻度
    plt.xticks(index, ('7', '8', '9', '10', '11', '12', '13', '14'))
    # plt.yticks(np.arange(0, 10000, 10))
    # 添加图例
    plt.legend(loc="upper right")
    plt.show()

       作图如下:

     

     

    来自为知笔记(Wiz)



  • 相关阅读:
    CF 633 E. Binary Table
    BZOJ 4589 Hard Nim
    不走弯路,微信小程序的快速入门?
    如果通过cookies和localStorage取值?
    Airbub 弃用React Native
    如何在登陆注册的时候,实现密码框的小眼睛的显示与与隐藏?
    js 实用封装 点击按钮复制到剪贴板
    css渐变写法 从左到右渐变三种颜色示例;
    vue-router 使用二级路由去实现子组件的显示和隐藏
    vue 路由传参中刷新页面参数丢失 及传参的几种方式?
  • 原文地址:https://www.cnblogs.com/jins-note/p/13460614.html
Copyright © 2011-2022 走看看