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()
作圖如下: