简体   繁体   English

功率谱由numpy.fft.fft

[英]power spectrum by numpy.fft.fft

The figure I plot via the code below is just a peak around ZERO, no matter how I change the data. 无论我如何更改数据,通过以下代码绘制的图形只是ZERO周围的峰值。 My data is just one column which records every timing points of some kind of signal. 我的数据只是一列,记录了某种信号的每个时间点。 Is the time_step a value I should define according to the interval of two neighbouring points in my data? time_step是我应该根据数据中两个相邻点的间隔定义的值吗?

data=np.loadtxt("timesequence",delimiter=",",usecols=(0,),unpack=True)

ps = np.abs(np.fft.fft(data))**2
time_step = 1

freqs = np.fft.fftfreq(data.size, time_step)
idx   = np.argsort(freqs)

pl.plot(freqs[idx], ps[idx])
pl.show()

As others have hinted at your signals must have a large nonzero component. 正如其他人暗示你的信号必须有一个大的非零组件。 A peak at 0 (DC) indicates the average value of your signal. 0(DC)处的峰值表示信号的平均值。 This is derived from the Fourier transform itself. 这来自傅里叶变换本身。 This cosine function cos(0)*ps(0) indicates a measure of the average value of the signal. 该余弦函数cos(0)* ps(0)表示信号平均值的度量。 Other Fourier transform components are cosine waves of varying amplitude which show frequency content at those values. 其他傅里叶变换分量是幅度变化的余弦波,其在这些值处显示频率成分。

Note that stationary signals will not have a large DC component as they are already zero mean signals. 请注意,静止信号不会有大的直流分量,因为它们已经是零均值信号。 If you do not want a large DC component then you should compute the mean of your signal and subtract values from that. 如果您不需要大型直流分量,那么您应该计算信号的平均值并从中减去值。 Regardless of whether your data is 0,...,999 or 1,...,1000, or even 1000, ..., 2000 you will get a peak at 0Hz. 无论您的数据是0,...,999还是1,...,1000,甚至1000,...,2000,您都将获得0Hz的峰值。 The only difference will be the magnitude of the peak since it measures the average value. 唯一的区别在于峰值的大小,因为它测量的是平均值。

data1 = arange(1000)
data2 = arange(1000)+1000
dataTransformed3 = data - mean(data)
data4 = numpy.zeros(1000)
data4[::10] = 1 #simulate a photon counter where a 1 indicates a photon came in at time indexed by array. 
# we could assume that the sample rate was 10 Hz for example
ps1 = np.abs(np.fft.fft(data))**2
ps2 = np.abs(np.fft.fft(data))**2
ps3 = np.abs(np.fft.fft(dataTransformed))**2

figure()
plot(ps1) #shows the peak at 0 Hz
figure()
plot(ps2) #shows the peak at 0 Hz
figure()
plot(ps3) #shows the peak at 1 Hz this is because we removed the mean value but since
#the function is a step function the next largest component is the 1 Hz cosine wave.
#notice the order of magnitude difference in the two plots.

Here is a bare-bones example that shows input and output with a peak as you'd expect it: 这是一个简单的示例,显示输入和输出的峰值,如您所期望的那样:

import numpy as np
from scipy.fftpack import rfft, irfft, fftfreq

time   = np.linspace(0,10,2000)
signal = np.cos(5*np.pi*time)

W = fftfreq(signal.size, d=time[1]-time[0])
f_signal = rfft(signal)

import pylab as plt
plt.subplot(121)
plt.plot(time,signal)
plt.subplot(122)
plt.plot(W,f_signal)
plt.xlim(0,10)
plt.show()

在此输入图像描述

I use rfft since, more than likely, your input signal is from a physical data source and as such is real. 我使用rfft因为很可能你的输入信号来自物理数据源,因此是真实的。

If you make your data all positive: 如果您使数据全部正面:

ps = np.abs(np.fft.fft(data))**2
time_step = 1

then most probably you will create a large 'DC', or 0 Hz component. 那么很可能你会创建一个大的“DC”或0 Hz组件。 So if your actual data has little amplitude, compared to that component, it will disappear from the plot, by the autoscaling feature. 因此,如果您的实际数据与该组件相比幅度很小,则它将通过自动缩放功能从绘图中消失。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM