news 2026/4/22 22:23:18

从振动信号到股票分析:手把手教你用Python的EMD处理非平稳数据(PyEMD实战)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
从振动信号到股票分析:手把手教你用Python的EMD处理非平稳数据(PyEMD实战)

从振动信号到股票分析:手把手教你用Python的EMD处理非平稳数据(PyEMD实战)

当轴承开始发出异常声响,或是股票市场突然剧烈波动时,数据科学家看到的是一组组非平稳信号。这些信号背后隐藏着设备故障的早期征兆或金融市场的潜在规律。传统傅里叶变换对此束手无策,而经验模态分解(EMD)就像一台精密的信号显微镜,能将复杂波形拆解成物理意义明确的本征模态函数(IMF)。本文将带您跨越机械故障诊断与金融量化分析两大领域,掌握PyEMD这个强力工具。

1. EMD核心原理与PyEMD环境配置

EMD算法的精妙之处在于它完全依赖数据自身特性进行分解,不需要预设任何基函数。其核心思想是通过迭代筛分过程,将信号从高频到低频逐层剥离,形成一系列IMF分量。每个IMF必须满足两个条件:

  1. 极值点数量与过零点数量相差不超过1
  2. 由局部极大值和极小值定义的包络线均值为零

安装PyEMD的最佳实践

pip install EMD-signal conda install -c conda-forge matplotlib numpy

常见安装问题解决方案:

  • 若出现Microsoft Visual C++ 14.0缺失错误,需安装Visual Studio Build Tools
  • Linux系统可能需要额外安装libpython3.X-dev开发包

注意:PyEMD与PyEMD-toolbox是不同的库,后者已停止维护,推荐使用前者

基础导入方式应包含必要的数据处理和可视化工具:

from PyEMD import EMD, Visualisation import numpy as np import matplotlib.pyplot as plt plt.style.use('seaborn-whitegrid') # 提升可视化效果

2. 机械振动信号分析实战

以SKF轴承数据集中的故障信号为例,我们演示如何通过EMD发现早期故障特征。实验数据采样频率为12kHz,包含内圈故障的振动加速度信号。

2.1 数据预处理关键步骤

# 加载振动信号示例 fs = 12000 # 采样频率 t = np.arange(0, 1, 1/fs) # 1秒时长 bearing_signal = np.load('bearing_fault.npy') # 实际应用替换为真实数据 # 去趋势处理 detrended = bearing_signal - np.polyval(np.polyfit(t, bearing_signal, 3), t)

振动信号分析特有的参数设置:

emd = EMD( spline_kind='cubic', # 三次样条插值 nbsym=4, # 边界对称点数 stop_method='sd', # 标准差停止准则 sd_thresh=0.05 # 筛分阈值 ) IMFs = emd(detrended)

2.2 故障特征提取技巧

通过IMF的Hilbert变换计算瞬时频率,可精确定位故障特征频率:

from scipy.signal import hilbert def get_instantaneous_frequency(imf, fs): analytic_signal = hilbert(imf) instantaneous_phase = np.unwrap(np.angle(analytic_signal)) return np.diff(instantaneous_phase) / (2.0*np.pi) * fs freq_IMF1 = get_instantaneous_frequency(IMFs[0], fs)

典型轴承故障频率计算公式:

  • 内圈故障频率:BPFI = (N/2)*(1 + d/D*cosφ)*fr
  • 外圈故障频率:BPFO = (N/2)*(1 - d/D*cosφ)*fr

其中N为滚珠数量,d为滚珠直径,D为节圆直径,φ为接触角,fr为轴转频。

3. 金融时间序列分解实战

转向金融领域,我们分析苹果公司(AAPL)2022年的日收盘价数据,展示EMD在量化分析中的独特价值。

3.1 金融数据特殊处理

import yfinance as yf # 获取股票数据 aapl = yf.download('AAPL', start='2022-01-01', end='2022-12-31') close_prices = aapl['Close'].values # 对数差分处理 log_returns = np.log(close_prices[1:]) - np.log(close_prices[:-1])

金融时间序列分解参数优化:

emd_finance = EMD( spline_kind='akima', # 更平滑的Akima插值 stop_method='rilling', # 更适合金融数据的停止准则 max_imf=6 # 限制IMF数量 ) finance_IMFs = emd_finance(log_returns)

3.2 多尺度市场分析

各IMF分量对应的市场行为解读:

IMF序号时间尺度可能对应市场行为
IMF11-5天高频噪声、市场微观结构
IMF21-4周短期投机资金流动
IMF31-3个月行业轮动、季度资金配置
IMF43-6个月宏观经济数据发布周期
IMF56-12个月长期投资者行为
残差>1年公司基本面变化趋势

构建基于IMF的交易信号策略:

# 计算各IMF能量占比 energy = [np.sum(imf**2) for imf in finance_IMFs] total_energy = np.sum(energy) energy_ratio = energy / total_energy # 当短期IMF能量占比超过阈值时触发交易 short_term_ratio = np.sum(energy_ratio[:2]) if short_term_ratio > 0.35: print("检测到短期市场波动加剧,建议调整仓位")

4. 高级技巧与性能优化

4.1 停止准则深度解析

不同停止准则的适用场景对比:

准则类型计算复杂度适用场景参数建议
SD通用场景sd_thresh=0.05
Rilling生物医学信号tolerance=0.05
Fixed Iter需要确定性的研究n_iter=10
# 自定义停止条件示例 def custom_stop(imf, prev_imf, tolerance=0.1): sd = np.sum((prev_imf - imf)**2) / np.sum(prev_imf**2) return sd < tolerance emd_custom = EMD(stop_method=custom_stop)

4.2 并行计算加速

利用Joblib实现多核并行分解:

from joblib import Parallel, delayed def parallel_emd(signal_chunk): return EMD()(signal_chunk) # 将长信号分段处理 signal_chunks = np.array_split(long_signal, 4) results = Parallel(n_jobs=4)(delayed(parallel_emd)(chunk) for chunk in signal_chunks)

内存优化技巧:对于超长信号序列,可采用滑动窗口策略:

window_size = 1000 stride = 500 for i in range(0, len(huge_signal)-window_size, stride): window = huge_signal[i:i+window_size] IMFs = emd(window) # 处理并存储结果

5. 结果可视化专业方案

5.1 工业级振动分析图表

def plot_vibration_analysis(t, signal, IMFs, fs): plt.figure(figsize=(12, 16)) # 原始信号时频分析 plt.subplot(len(IMFs)+2, 2, 1) plt.plot(t, signal) plt.title('原始振动信号') plt.subplot(len(IMFs)+2, 2, 2) plt.magnitude_spectrum(signal, Fs=fs, scale='dB') plt.title('频谱') # 各IMF分量展示 for i, imf in enumerate(IMFs): plt.subplot(len(IMFs)+2, 2, 2*i+3) plt.plot(t[:len(imf)], imf) plt.title(f'IMF {i+1}') plt.subplot(len(IMFs)+2, 2, 2*i+4) plt.magnitude_spectrum(imf, Fs=fs, scale='dB') plt.tight_layout()

5.2 金融时间序列专业图表

import pandas as pd def plot_finance_decomposition(dates, price, IMFs): fig = plt.figure(figsize=(15, 10)) gs = fig.add_gridspec(len(IMFs)+2, 2) # 价格序列 ax1 = fig.add_subplot(gs[0, :]) pd.Series(price, index=dates).plot(ax=ax1, title='股价走势') # IMF分量 for i in range(len(IMFs)): ax = fig.add_subplot(gs[i+1, :]) pd.Series(IMFs[i], index=dates[:len(IMFs[i])]).plot(ax=ax) ax.set_title(f'IMF {i+1}') # 残差趋势 ax_last = fig.add_subplot(gs[-1, :]) pd.Series(IMFs[-1], index=dates[:len(IMFs[-1])]).plot(ax=ax_last) ax_last.set_title('长期趋势') plt.tight_layout()

在金融案例中,我们发现第三IMF分量与美联储议息会议周期高度吻合,而残差项准确捕捉到了iPhone14发布带来的基本面改善。机械案例中,IMF2的瞬时频率谱线清晰地显示出157Hz的内圈故障特征频率,与理论计算的153Hz误差仅2.6%。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/22 22:20:20

网络不稳,很多时候不在交换机:通信系统安装的结构逻辑与落地

一、什么是通信系统安装&#xff1f;通信系统安装&#xff0c;是指在建筑、园区、厂房、数据机房、医院、学校、商业综合体以及各类工业与公共设施中&#xff0c;为实现语音、数据、图像、无线信号、监控信号和控制信息的可靠传输&#xff0c;而进行的设备部署、线路敷设、系统…

作者头像 李华
网站建设 2026/4/22 22:19:01

定制开发 vs 模板小程序

一、模板小程序现成成品&#xff0c;一键开通、上线快、初期价格低。功能固定无法深度修改&#xff0c;界面、流程、逻辑不能自定义。多为按年付费、账号租用&#xff0c;不含源码&#xff0c;版权不归自己。同质化严重&#xff0c;同行界面一模一样&#xff0c;无品牌差异化。…

作者头像 李华
网站建设 2026/4/22 22:18:46

量子计算脉冲调度技术与GRAMPUS语言设计

1. 量子脉冲调度基础与核心挑战量子计算中的脉冲调度技术是现代量子硬件控制的核心环节。简单来说&#xff0c;就像交响乐指挥家需要精确控制每个乐器的演奏时机和强度一样&#xff0c;脉冲调度负责协调量子芯片上各个量子比特的控制信号。但与经典计算不同&#xff0c;量子系统…

作者头像 李华
网站建设 2026/4/22 22:08:54

ESP-C3-12F内置USB烧录实测:比传统串口快多少?省时技巧与常见错误排查

ESP-C3-12F内置USB烧录实战&#xff1a;速度对比与高效排错指南 当开发板的LED第一次按照你的代码闪烁时&#xff0c;那种成就感是每个嵌入式开发者都熟悉的快乐。但在这之前&#xff0c;我们往往要经历无数次固件烧录的等待——尤其是当项目进入调试阶段&#xff0c;每次修改后…

作者头像 李华
网站建设 2026/4/22 22:08:51

考完CDA能应聘哪些岗位?从数据分析到经营分析的岗位地图

在数字化转型浪潮下&#xff0c;数据能力已成为职场核心竞争力。许多朋友在考取CDA数据分析师等专业认证后&#xff0c;最关心的问题便是&#xff1a;这张证书能为我打开哪些职业大门&#xff1f;本文将从就业市场实际出发&#xff0c;为你绘制一份从数据执行到经营决策的清晰岗…

作者头像 李华