暂时打断一下滤波专题,插播一条EMD在python中实现方法的文章。
本篇是Mr.看海:这篇文章能让你明白经验模态分解(EMD)——EMD在MATLAB中的实现方法的姊妹篇,也就是要在python中实现EMD分解并画图。
在python环境中,PyEMD包是比较好用的。PyEMD中不仅包含了EMD分解方法,还包括EEMD和CEEMDAN,以及绘制简易图片的方式。
PyEMD的官方文档在这里:Intro - PyEMD 0.2.13 documentation
最简便的安装方式是使用pip安装,也就是在命令行窗口执行:
pip install EMD-signal
注意不是pip install PyEMD哈
另外还有一种手动下载源码安装的方式,具体方式在上边的官方文档里,这里就不详细介绍了。大多数情况下使用pip安装就行。
接下来就可以编写python脚本了,首先需要导入PyEMD工具包(以及过会儿要用的matplotlib,如果没有安装,需要在命令行窗口执行:pip install Matplotlib):
from PyEMD import EMD
import pylab as plt
生成一个随机信号:
import numpy as np
s = np.random.random(100)
执行EMD分解:
emd = EMD()
IMF = emd.emd(s)
工具包内置了Visualisation可视化工具,但是使用下来并不是特别好用,这里使用Matplotlib画图。
官方提供了一段画图的程序:
N = IMF.shape[0]+1
# Plot results
plt.subplot(N,1,1)
plt.plot(t, s, 'r')
plt.title("Input signal")
plt.xlabel("Time [s]")
for n, imf in enumerate(IMF):
plt.subplot(N,1,n+2)
plt.plot(t, imf, 'g')
plt.title("IMF "+str(n+1))
plt.xlabel("Time [s]")
plt.tight_layout()
plt.savefig('simple_example')
plt.show()
画出来是这样的:
咋说呢,有点差强人意。python绘制子图像的标题显示有些小bug,我们可以把它挪到左边,另外按照惯例,我们可以把最后一个分量的名称改成res。
我们在上述代码的基础上再次进行了封装,实现“一行代码”画图的目的。因为之前我们对MATLAB的“类EMD”分解方法画图有了一系列的方法,这里我们作为姊妹篇,在画图风格上也与之保持一致。
比如绘制EMD分解的时域图像,只需要调用这样一句:
imf = funEMD.pEMD(data,t) #t为数据的时间轴,第二个入口参数也可以输入采样频率fs,会自动计算时间轴
画出来的图是这样的:
这样是不是更符合习惯一些了。
此外还可以绘制时域和频域的对比图,也只需要调用这样一句代码:
imf = funEMD.pEMDandFFT(data,t) #t为数据的时间轴,第二个入口参数也可以输入采样频率fs,会自动计算时间轴
当然啦,如果你直接copy上边的两行代码是画不了图的,因为上述代码运行还依赖一些程序以及环境,不过总体来说还是比较简便易用的了。
需要注意的一点,上边的图片中用到的分析对象信号和在MATLAB那篇文章中是一样的,但是分解结果并不相同。虽然EMD分解的原理是相对明确的,但是在具体的编程实现的过程中还涉及很多具体计算过程,比如包络的求取、停止准则的选定等等,其中参数或者计算方式的变化都会影响到最终结果,MATLAB和python的EMD实现是两个不同的库,在这些细节之处难免存在差异(即使都是用在MATLAB上的官方库和第三方库之间都会有差异),所以使用python和MATLAB进行EMD分解得到的结果不同是正常现象。
如果想要获取上边的封装画图函数和应用案例,可以在下边的链接获取:
EMD画图工具(python版) | 工具箱文档
由于滤波专题讲完之后准备正式开始神经网络专题了,其中关于分类、预测等内容计划同时介绍在MATLAB和python两个平台上的实现方法,考虑到之前专栏基本都是使用MATLAB编程的,所以小编将会开启python补完计划,对于之前已经实现的类EMD分解、特征提取、降噪等等会逐步完善在python中的具体代码实现,希望能保住到有需要的同学们吧。
欢迎持续关注我的专栏与信号处理有关的那些东东。