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

[Python] python信号处理绘制信号频谱

python信号处理绘制信号频谱:scipy.signal.welch

文章目录

  • python信号处理绘制信号频谱:`scipy.signal.welch`
      • 一、函数介绍
      • 二、核心参数详解
      • 三、返回值
      • 四、算法原理
      • 五、关键特性
      • 六、完整示例
      • 七、应用场景推荐配置
      • 八、常见问题解决
      • 九、与FFT方法的对比

scipy.signal.welch 是 Python 中用于计算信号功率谱密度(PSD)的常用函数,采用 Welch 方法实现。这种方法通过将信号分段、加窗和平均来减少频谱估计的方差。以下是详细说明:

一、函数介绍

f, Pxx = scipy.signal.welch(x,                   # 输入信号fs=1.0,              # 采样频率window='hann',       # 窗函数nperseg=None,        # 每段长度noverlap=None,       # 重叠点数nfft=None,           # FFT长度detrend='constant',  # 去趋势方法return_onesided=True,# 是否返回单边谱scaling='density',   # 缩放类型axis=-1,             # 计算轴average='mean'       # 平均方法
)

二、核心参数详解

参数默认值说明
x-输入信号(1D数组或2D数组)
fs1.0采样频率(Hz),影响频率坐标
window‘hann’窗函数类型:‘hann’(汉宁窗)、‘hamming’(汉明窗)、‘blackman’(布莱克曼窗)、‘boxcar’(矩形窗)等
npersegNone每段长度(点数)。None时取256或len(x)较小值
noverlapNone段间重叠点数。None时为nperseg // 2(50%重叠)
nfftNoneFFT长度。None时等于nperseg;大于nperseg时进行零填充
detrend‘constant’去趋势方法:‘constant’(去均值)、‘linear’(去线性趋势)、False(不去趋势)
scaling‘density’输出缩放:‘density’(PSD, V²/Hz)、‘spectrum’(功率谱, V²)
average‘mean’平均方法:‘mean’(算术平均)、‘median’(中位数平均)

三、返回值

返回值说明
f频率数组(Hz)
Pxx功率谱密度数组(单位取决于scaling参数)

四、算法原理

  1. 分段:将长度为N的信号分成K段

    • 每段长度:nperseg
    • 段数: K = N − noverlap nperseg − noverlap K = \frac{N - \text{noverlap}}{\text{nperseg} - \text{noverlap}} K=npersegnoverlapNnoverlap
  2. 处理每段

    for segment in segments:# 1. 去趋势 (detrend)# 2. 加窗 (apply window)# 3. 计算FFT# 4. 计算周期图: |FFT|²
    
  3. 平均:对所有段的周期图进行平均
    P x x = avg ( ∣ F F T k ∣ 2 ) f s ⋅ S 2 P_{xx} = \frac{\text{avg}(|FFT_k|^2)}{f_s \cdot S_2} Pxx=fsS2avg(FFTk2)
    其中 S 2 = ∑ n = 0 N − 1 w [ n ] 2 S_2 = \sum_{n=0}^{N-1} w[n]^2 S2=n=0N1w[n]2 是窗函数的能量补偿因子

五、关键特性

  1. 方差减小:通过分段平均降低随机噪声影响
  2. 频率分辨率 Δ f = f s nperseg \Delta f = \frac{f_s}{\text{nperseg}} Δf=npersegfs
    • 增加nperseg ➔ 提高分辨率
    • 增加noverlap ➔ 增加段数(降低方差)
  3. 偏置-方差权衡
    • 长分段:低偏置、高方差
    • 短分段:高偏置、低方差

六、完整示例

import numpy as np
from scipy import signal
import matplotlib.pyplot as plt# 生成测试信号
fs = 1000  # 采样率
t = np.arange(0, 1, 1/fs)
x = np.sin(2*np.pi*50*t) + 0.5*np.sin(2*np.pi*120*t)  # 50Hz + 120Hz
x += 0.8 * np.random.randn(len(t))  # 添加高斯噪声# 计算功率谱密度
f, Pxx = signal.welch(x,fs=fs,window='hann',      # 汉宁窗(默认)nperseg=1024,       # 每段1024点noverlap=512,       # 50%重叠nfft=2048,          # 2048点FFT(零填充)detrend='constant', # 去除均值scaling='density'   # 功率谱密度
)# 绘制结果
plt.figure(figsize=(10, 5))
plt.semilogy(f, Pxx)  # 对数坐标
plt.title('Power Spectral Density (Welch Method)')
plt.xlabel('Frequency [Hz]')
plt.ylabel('PSD [V²/Hz]')
plt.xlim(0, 200)  # 限制显示范围
plt.grid(True)
plt.show()

绘制得到频谱图如下:
在这里插入图片描述

七、应用场景推荐配置

场景推荐参数
平稳信号nperseg=1024, noverlap=512
低信噪比信号增加noverlap(如75%)
高分辨率需求增大nperseg(牺牲计算速度)
瞬态信号分析减小nperseg,使用detrend='linear'
精确峰值测量使用window='flattop'(平坦窗)

八、常见问题解决

  1. 频率泄露

    • 改用旁瓣衰减更好的窗(如window='blackman'
    • 增加nperseg提高分辨率
  2. 弱信号被淹没

    # 使用中位数平均增强弱信号可见性
    f, Pxx = welch(..., average='median')
    
  3. 直流偏移影响

    # 确保去趋势
    f, Pxx = welch(..., detrend='constant')
    
  4. 频率坐标错误

    • 检查fs是否设置正确
    • 确认return_onesided=True(实信号)

九、与FFT方法的对比

特性welch直接FFT
方差
计算量中高
频率分辨率可调节固定
抗噪能力
适合信号类型长时记录、噪声信号短信号、瞬态信号

Welch 方法特别适合分析实际工程信号,在噪声环境下能提供更稳定的频谱估计结果。


研究学习不易,点赞易。
工作生活不易,收藏易,点收藏不迷茫 :)


相关文章:

  • Transformer核心原理
  • SIFT 算法原理详解
  • 使用 Python 制作 GIF 动图,并打包为 EXE 可执行程序
  • Office文档图片批量导出工具
  • 新德通科技:以创新驱动光通信一体化发展,赋能全球智能互联
  • [yolov11改进系列]基于yolov11使用FasterNet替换backbone用于轻量化网络的python源码+训练源码
  • 欢乐熊大话蓝牙知识14:用 STM32 或 EFR32 实现 BLE 通信模块:从0到蓝牙,你也能搞!
  • Spring AI Alibaba + Nacos 动态 MCP Server 代理方案
  • 数据驱动在线教育平台优化:用数据帮你变成“教书匠+数据控”
  • 6.4 note
  • React-native之Flexbox
  • 数字乡村治理整体解决方案
  • 【Java实例-神秘年龄】用Java挑战你的直觉
  • 集合类基础概念
  • 免费论文查重与AI检测工具推荐
  • 多线程编程的黄金三角模型
  • 每日算法刷题Day21 6.3:leetcode二分答案2道题,用时1h20min(有点慢)
  • 【时时三省】(C语言基础)数组作为函数参数
  • js-day7
  • ssm学习笔记day04
  • 优秀的网页网站设计/东莞网站优化公司
  • 杭州做网站公司哪家好/百度自然搜索排名优化
  • 阀门专业网站建设/关键词是怎么排名的
  • 小说盗版网站怎么做的/索引擎优化 seo
  • 哪个网站可以做服装批发衣服/国内做网站比较好的公司
  • 微信小程序开发网站/seo网站内部优化方案