我是python以及信号处理的新手。我试图在信号的某个频率范围内计算mean
值。
我想做的是如下:
import numpy as np
data = <my 1d signal>
lF = <lower frequency>
uF = <upper frequency>
ps = np.abs(np.fft.fft(data)) ** 2 #array of power spectrum
time_step = 1.0 / 2000.0
freqs = np.fft.fftfreq(data.size, time_step) # array of frequencies
idx = np.argsort(freqs) # sorting frequencies
sum = 0
c =0
for i in idx:
if (freqs[i] >= lF) and (freqs[i] <= uF) :
sum += ps[i]
c +=1
avgValue = sum/c
print 'mean value is=',avgValue
我认为计算很好,但是对于超过15GB的数据并且处理时间呈指数增长需要花费很多时间。是否有任何最快的方式可以使我能够以最快的方式在某个频率范围内获得功率谱的平均值。提前谢谢。
编辑1
我跟着this code计算了功率谱。
编辑2
This没有回答我的问题,因为它计算了整个数组/列表的平均值,但我希望平均超过数组的一部分。
编辑3
jez使用面膜的解决方案减少了时间。实际上我有超过10个1D信号通道,我想以相同的方式处理它们,即每个通道的范围内的平均频率分开。我认为python循环很慢。那有什么替代品吗? 像这样:
for i in xrange(0,15):
data = signals[:, i]
ps = np.abs(np.fft.fft(data)) ** 2
freqs = np.fft.fftfreq(data.size, time_step)
mask = np.logical_and(freqs >= lF, freqs <= uF )
avgValue = ps[mask].mean()
print 'mean value is=',avgValue
答案 0 :(得分:7)
以下内容对选定区域执行平均值:
mask = numpy.logical_and( freqs >= lF, freqs <= uF )
avgValue = ps[ mask ].mean()
为了正确缩放已计算为abs(
fft系数)**2
的功效值,您需要乘以(2.0 / len(data))**2
(Parseval's theorem)
请注意,如果您的频率范围包含奈奎斯特频率,则会略微繁琐 - 为了获得精确结果,那么单频分量的处理将需要取决于data.size
是偶数还是奇数。因此,为简单起见,请确保uF
严格小于max(freqs)
。 [出于类似原因,您应该确保lF > 0
。]
原因很难解释,甚至更难以纠正,但基本上:DC组件在DFT中表示一次,而大多数其他频率组件表示两次(正频率和负频率)每次半幅。更令人讨厌的例外是奈奎斯特频率,如果信号长度是偶数,则以全幅度表示一次,如果信号长度是奇数,则以半幅度表示两次。如果你平均幅度,所有这些都不会影响你:在线性系统中,被表示两次补偿为半幅度。但是你要平均 power ,即在平均值之前对值进行平方,所以这种补偿并没有成功。
I've pasted my code了解所有这些。此代码还说明了如何处理堆叠在一个numpy数组中的多个信号,这些信号解决了有关在多通道情况下避免循环的后续问题。请务必向axis
和我的numpy.fft.fft()
提供正确的fft2ap()
参数 。
答案 1 :(得分:2)
如果阵列的功率为2,则使用FFT会更容易。当你执行fft时,频率范围从-pi / timestep到pi / timestep(假设频率定义为w = 2 * pi / t,如果使用f = 1 / t表示,则相应地更改值。您的频谱排列为0到minfreqq - maxfreq为零。你现在可以使用fftshift功能交换频率,你的频谱看起来像minfreq - DC - maxfreq。现在您可以轻松确定所需的频率范围,因为它已经排序。
频率步长dw = 2 * pi /(时间跨度)或最大频率/(N / 2)其中N是阵列大小。 N / 2点是DC或0频率。第N个位置是最大频率,现在您可以轻松确定您的范围
Lower_freq_indx=N/2+N/2*Lower_freq/max_freq
Higher_freq_index=N/2+N/2*Higher_freq/Max_freq
avg=sum(ps[lower_freq_indx:Higher_freq_index]/(Higher_freq_index-Lower_freq_index)
我希望这会有所帮助
问候