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()
作图如下:
------------------------------------------------------------未完待续------------------------------------------------------------------------