当前位置: 首页 > news >正文

别再死记硬背公式了!用Python+NumPy手把手带你玩转随机信号(附平稳性检验代码)

用Python实战解析随机信号:从统计特征到平稳性检验

在传感器监测、金融时间序列分析或语音处理中,我们常遇到看似毫无规律的数据波动。传统教学中复杂的数学公式往往让人望而生畏,而实际工程更需要的是能快速上手的代码实现。本文将以Jupyter Notebook为战场,用NumPy和Matplotlib这些Python利器,带您直击随机信号分析的核心实战技能。

1. 理解随机信号的DNA:统计特征

随机信号就像一群自由奔放的野马,虽然单个轨迹难以预测,但群体行为却存在规律。我们首先需要掌握描述这些规律的三大核心指标:

import numpy as np import matplotlib.pyplot as plt # 生成模拟随机信号 np.random.seed(42) stationary_signal = np.cumsum(np.random.randn(1000)) * 0.1 non_stationary = np.concatenate([ np.random.normal(0, 1, 300), np.random.normal(2, 1.5, 400), np.random.normal(-1, 0.8, 300) ])

1.1 均值与方差:信号的身份证

均值反映信号的基准线,方差则体现波动强度。对于上述模拟信号:

def print_stats(signal, name): print(f"{name}信号统计:") print(f"均值: {np.mean(signal):.4f}") print(f"方差: {np.var(signal):.4f}") print(f"标准差: {np.std(signal):.4f}\n") print_stats(stationary_signal, "平稳") print_stats(non_stationary, "非平稳")

注意:实际工程中建议使用pandas.DataFrame.rolling()计算滑动统计量,能更直观观察局部特征变化。

1.2 概率密度分布:信号的指纹图谱

直方图和核密度估计(KDE)比单一统计量更能揭示信号本质:

from scipy.stats import gaussian_kde plt.figure(figsize=(12,5)) plt.subplot(121) plt.hist(stationary_signal, bins=30, density=True, alpha=0.6) kde = gaussian_kde(stationary_signal) xvals = np.linspace(min(stationary_signal), max(stationary_signal), 200) plt.plot(xvals, kde(xvals), 'r-') plt.title("平稳信号分布") plt.subplot(122) plt.hist(non_stationary, bins=30, density=True, alpha=0.6) kde = gaussian_kde(non_stationary) xvals = np.linspace(min(non_stationary), max(non_stationary), 200) plt.plot(xvals, kde(xvals), 'r-') plt.title("非平稳信号分布") plt.show()

2. 平稳性检验:信号稳定性的照妖镜

平稳性是许多信号处理算法的前提假设,下面介绍两种实用的检验方法。

2.1 滑动窗口检验法

通过观察统计量随时间的变化来判断平稳性:

def rolling_stat_test(signal, window_size=100): means = [np.mean(signal[i:i+window_size]) for i in range(0, len(signal)-window_size)] stds = [np.std(signal[i:i+window_size]) for i in range(0, len(signal)-window_size)] plt.figure(figsize=(12,4)) plt.subplot(121) plt.plot(means) plt.title("滑动均值变化") plt.subplot(122) plt.plot(stds) plt.title("滑动标准差变化") plt.show() rolling_stat_test(stationary_signal) rolling_stat_test(non_stationary)

2.2 ADF单位根检验

Augmented Dickey-Fuller检验是时间序列分析中的经典方法:

from statsmodels.tsa.stattools import adfuller def adf_test(signal): result = adfuller(signal) print('ADF统计量: %f' % result[0]) print('p值: %f' % result[1]) print('临界值:') for key, value in result[4].items(): print('\t%s: %.3f' % (key, value)) if result[1] < 0.05: print("拒绝原假设,信号可能平稳") else: print("无法拒绝原假设,信号可能非平稳") print("平稳信号检验结果:") adf_test(stationary_signal) print("\n非平稳信号检验结果:") adf_test(non_stationary)

3. 实战案例:EEG信号分析

让我们用真实的EEG数据(来自MNE库)演示完整分析流程:

# 安装MNE库: pip install mne import mne from mne.datasets import sample data_path = sample.data_path() raw_fname = data_path / 'MEG/sample/sample_audvis_filt-0-40_raw.fif' raw = mne.io.read_raw_fif(raw_fname, preload=True) # 选取EEG通道 eeg_data = raw.pick_types(eeg=True).get_data()[0, :10000]

3.1 特征提取与可视化

plt.figure(figsize=(15,5)) plt.plot(eeg_data[:1000]) plt.title("EEG信号片段") plt.xlabel("采样点") plt.ylabel("幅值(μV)") plt.show() # 计算统计特征 eeg_features = { "均值": np.mean(eeg_data), "方差": np.var(eeg_data), "偏度": mne.stats.stats.skew(eeg_data), "峰度": mne.stats.stats.kurtosis(eeg_data) } print("EEG信号特征:") for k, v in eeg_features.items(): print(f"{k}: {v:.4f}")

3.2 平稳性分析

# 分段平稳性检验 segment_length = 2000 for i in range(0, len(eeg_data), segment_length): segment = eeg_data[i:i+segment_length] print(f"\n段{i//segment_length}检验结果:") adf_test(segment)

4. 进阶技巧:处理非平稳信号

当检测到非平稳性时,常用的处理方法包括:

方法原理适用场景Python实现
差分法计算相邻数据点的差值趋势性非平稳np.diff()
对数变换压缩数据尺度方差变化型np.log1p()
分段处理将信号划分为准平稳段突变型非平稳自定义分段
小波变换时频域联合分析复杂非平稳pywt

差分法示例:

diff_signal = np.diff(non_stationary) plt.figure(figsize=(12,4)) plt.subplot(121) plt.plot(non_stationary) plt.title("原始信号") plt.subplot(122) plt.plot(diff_signal) plt.title("一阶差分信号") plt.show() print("差分后平稳性检验:") adf_test(diff_signal)

在金融时间序列分析中,我经常发现简单的对数差分组合就能使大多数价格序列变得平稳。但要注意过度差分会导致信息损失,实践中需要通过ACF/PACF图辅助判断最优差分阶数。

http://www.jsqmd.com/news/758913/

相关文章:

  • mirrors/monster-labs/control_v1p_sd15_qrcode_monster社区精选作品赏析:创意二维码设计灵感
  • mirrors/monster-labs/control_v1p_sd15_qrcode_monster用户体验改进建议:让模型更易用
  • 终极指南:XHS-Downloader高效批量下载小红书无水印内容的完整解决方案
  • ECS 磁盘 IO 等待过高导致系统卡顿怎么排查优化?
  • qmcdump终极指南:3步快速解密QQ音乐加密文件,实现跨平台自由播放
  • 如何快速掌握Switch大气层系统:新手终极完整指南
  • WeiClaw:基于官方接口的全模态微信AI Agent网关部署指南
  • KubeArmor实战:保护WordPress和MySQL应用的安全策略设计
  • 应对高并发场景时Taotoken的路由与容灾能力应用思路
  • Jetson Orin NX上Qt Creator安装踩坑实录:手把手解决libglu1-mesa和libxext6依赖版本冲突
  • MediaPipe TouchDesigner完整指南:三步实现GPU加速的实时AI视觉特效
  • RPG Maker Decrypter:终极游戏资源解密工具深度解析
  • 3个步骤告别Windows系统卡顿:WinUtil让你的电脑重获新生
  • 教育领域新应用:基于hf_mirrors/ai-gitcode/seamless-m4t-v2-large的多语言学习助手开发
  • m4s-converter:3步解锁B站缓存视频,跨设备播放的终极解决方案
  • 别再只调PI了!手把手教你用Simulink给PMSM速度环搭一个滑模控制器(SMC)
  • 如何快速配置编辑器与IDE插件:idiomatic.js工具链的完整指南
  • 从 API 调用日志看 Taotoken 路由容灾机制的实际运行
  • Python开发者五分钟上手Taotoken调用GPT与国产大模型
  • mirrors/unsloth/llama-3-8b-bnb-4bit容器化:Docker镜像构建与优化完整指南
  • 创业团队如何利用 Taotoken 多模型能力低成本验证产品创意
  • 内容创作团队如何借助 Taotoken 调用不同模型优化文案生成
  • 研华DAQNavi API设计精要:从‘端口’与‘通道’概念理解工业数据采集的编程模型
  • LeRobot机器人AI框架完整指南:从零开始构建智能机器人控制系统
  • 5分钟解锁B站4K会员视频下载:bilibili-downloader深度解密与实战指南
  • 终极指南:如何用Comfy-Photoshop-SD插件将AI绘画无缝融入Photoshop工作流
  • Anno 1800 Mod Loader终极指南:解锁无限游戏自定义可能
  • Vue-Element-Admin中的Promise异步处理:终极请求封装与错误处理指南
  • Win11Debloat终极指南:3分钟打造纯净高效的Windows系统
  • 空间智能与神经渲染技术在三维重建中的应用