信号的 Numpy 均方根 (RMS) 平滑 [英] Numpy Root-Mean-Squared (RMS) smoothing of a signal

查看:41
本文介绍了信号的 Numpy 均方根 (RMS) 平滑的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个肌电数据信号,我应该(科学论文的明确建议)使用 RMS 进行平滑处理.

I have a signal of electromyographical data that I am supposed (scientific papers' explicit recommendation) to smooth using RMS.

我有以下工作代码,产生所需的输出,但它比我想象的要慢.

I have the following working code, producing the desired output, but it is way slower than I think it's possible.

#!/usr/bin/python
import numpy
def rms(interval, halfwindow):
    """ performs the moving-window smoothing of a signal using RMS """
    n = len(interval)
    rms_signal = numpy.zeros(n)
    for i in range(n):
        small_index = max(0, i - halfwindow)  # intended to avoid boundary effect
        big_index = min(n, i + halfwindow)    # intended to avoid boundary effect
        window_samples = interval[small_index:big_index]

        # here is the RMS of the window, being attributed to rms_signal 'i'th sample:
        rms_signal[i] = sqrt(sum([s**2 for s in window_samples])/len(window_samples))

    return rms_signal

我已经看到了一些关于移动窗口循环优化的 dequeitertools 建议,以及来自 numpy 的 convolve,但我不能弄清楚如何使用它们来完成我想要的.

I have seen some deque and itertools suggestions regarding optimization of moving window loops, and also convolve from numpy, but I couldn't figure it out how to accomplish what I want using them.

此外,我不再关心避免边界问题,因为我最终得到了大数组和相对较小的滑动窗口.

Also, I do not care to avoid boundary problems anymore, because I end up having large arrays and relatively small sliding windows.

感谢阅读

推荐答案

可以使用卷积来执行您所指的操作.为了处理脑电信号,我也做了几次.

It is possible to use convolution to perform the operation you are referring to. I did it a few times for processing EEG signals as well.

import numpy as np
def window_rms(a, window_size):
  a2 = np.power(a,2)
  window = np.ones(window_size)/float(window_size)
  return np.sqrt(np.convolve(a2, window, 'valid'))

分解后,np.power(a, 2) 部分创建了一个与 a 维度相同的新数组,但每个值都是平方的.np.ones(window_size)/float(window_size) 产生一个数组或长度window_size,其中每个元素是1/window_size.所以卷积有效地产生了一个新数组,其中每个元素 i 等于

Breaking it down, the np.power(a, 2) part makes a new array with the same dimension as a, but where each value is squared. np.ones(window_size)/float(window_size) produces an array or length window_size where each element is 1/window_size. So the convolution effectively produces a new array where each element i is equal to

(a[i]^2 + a[i+1]^2 + … + a[i+window_size]^2)/window_size

这是移动窗口内数组元素的 RMS 值.它应该以这种方式表现得非常好.

which is the RMS value of the array elements within the moving window. It should perform really well this way.

但是请注意,np.power(a, 2) 会生成一个相同维度的 new 数组.如果 areally 大,我的意思是足够大以至于它不能在内存中容纳两次,您可能需要一个策略来修改每个元素.此外,'valid' 参数指定丢弃边框效果,从而生成由 np.convolve() 生成的较小数组.您可以通过指定 'same' 来保留所有内容(请参阅 文档).

Note, though, that np.power(a, 2) produces a new array of same dimension. If a is really large, I mean sufficiently large that it cannot fit twice in memory, you might need a strategy where each element are modified in place. Also, the 'valid' argument specifies to discard border effects, resulting in a smaller array produced by np.convolve(). You could keep it all by specifying 'same' instead (see documentation).

这篇关于信号的 Numpy 均方根 (RMS) 平滑的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆