首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >numpy.fft.fft和numpy.fft.fftfreq有什么区别?

numpy.fft.fft和numpy.fft.fftfreq有什么区别?
EN

Stack Overflow用户
提问于 2020-01-30 04:59:43
回答 2查看 20.9K关注 0票数 9

我正在分析时间序列数据,并希望提取5个主要的频率成分,并用作训练机器学习模型的特征。我的数据集是921 x 10080。每一行都是一个时间序列,总共有921行。

在探索可能的方法时,我遇到了各种函数,包括numpy.fft.fftnumpy.fft.fftfreqDFT .我的问题是,这些函数对数据集做了什么,这些函数之间的区别是什么?

对于Numpy.fft.fft,Numpy docs状态:

代码语言:javascript
复制
Compute the one-dimensional discrete Fourier Transform.

This function computes the one-dimensional n-point discrete Fourier Transform (DFT) with the efficient Fast Fourier Transform (FFT) algorithm [CT].

时间为numpy.fft.fftfreq

代码语言:javascript
复制
numpy.fft.fftfreq(n, d=1.0)
Return the Discrete Fourier Transform sample frequencies.

The returned float array f contains the frequency bin centers in cycles per unit of the sample spacing (with zero at the start). For instance, if the sample spacing is in seconds, then the frequency unit is cycles/second.

但这并不是真的和我说话,可能是因为我没有信号处理的背景知识。我应该在我的案件中使用哪一种功能?提取数据集每一行的前5个主频率和振幅分量?谢谢

更新:

使用fft返回下面的结果。我的意图是获得每个时间序列的前5个频率和振幅值,但它们是频率分量吗?

下面是代码:

代码语言:javascript
复制
def get_fft_values(y_values, T, N, f_s):
    f_values = np.linspace(0.0, 1.0/(2.0*T), N//2)
    fft_values_ = rfft(y_values)
    fft_values = 2.0/N * np.abs(fft_values_[0:N//2])
    return f_values[0:5], fft_values[0:5]  #f_values - frequency(length = 5040) ; fft_values - amplitude (length = 5040)

t_n = 1
N = 10080
T = t_n / N
f_s = 1/T

result = pd.DataFrame(df.apply(lambda x: get_fft_values(x, T, N, f_s), axis =1)) 
result

和输出

代码语言:javascript
复制
0   ([0.0, 1.000198452073824, 2.000396904147648, 3.0005953562214724, 4.000793808295296], [52.91299603174603, 1.2744877093061115, 2.47064631896607, 1.4657299825335832, 1.9362280837538701])
1   ([0.0, 1.000198452073824, 2.000396904147648, 3.0005953562214724, 4.000793808295296], [57.50430555555556, 4.126212552498241, 2.045294347349226, 0.7878668631936439, 2.6093502232989976])
2   ([0.0, 1.000198452073824, 2.000396904147648, 3.0005953562214724, 4.000793808295296], [52.05765873015873, 0.7214089616631307, 1.8547819994826562, 1.3859749465142301, 1.1848485830307878])
3   ([0.0, 1.000198452073824, 2.000396904147648, 3.0005953562214724, 4.000793808295296], [53.68928571428572, 0.44281647644149114, 0.3880646059685434, 2.3932194091895043, 0.22048418335196407])
4   ([0.0, 1.000198452073824, 2.000396904147648, 3.0005953562214724, 4.000793808295296], [52.049007936507934, 0.08026717757664162, 1.122163085234073, 1.2300320578011028, 0.01109727616896663])
... ...
916 ([0.0, 1.000198452073824, 2.000396904147648, 3.0005953562214724, 4.000793808295296], [74.39303571428572, 2.7956204803382096, 1.788360577194303, 0.8660509272194551, 0.530400826933975])
917 ([0.0, 1.000198452073824, 2.000396904147648, 3.0005953562214724, 4.000793808295296], [51.88751984126984, 1.5768804453161231, 0.9932384706239461, 0.7803585797514547, 1.6151532436755451])
918 ([0.0, 1.000198452073824, 2.000396904147648, 3.0005953562214724, 4.000793808295296], [52.16263888888889, 1.8672674706267687, 0.9955183554654834, 1.0993971449470716, 1.6476405255363171])
919 ([0.0, 1.000198452073824, 2.000396904147648, 3.0005953562214724, 4.000793808295296], [59.22579365079365, 2.1082518972190183, 3.686245044113031, 1.6247500816133893, 1.9790245755039324])
920 ([0.0, 1.000198452073824, 2.000396904147648, 3.0005953562214724, 4.000793808295296], [59.32333333333333, 4.374568790482763, 1.3313693716184536, 0.21391538068483704, 1.414774377287436])
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-01-30 05:09:51

首先要了解信号的时域和频域表示。下图显示了几种常见的基本信号类型及其时域和频域表示。

密切关注正弦曲线,我将用它来说明fft和fftfreq之间的区别。

傅里叶变换是您的时域和频域表示之间的门户。因此

numpy.fft.fft() -返回傅里叶变换。这将有真实的部分和想象的部分。实数和虚部本身并不特别有用,除非你对数据窗口中心周围的对称属性感兴趣(偶数和奇数)。

numpy.fft.fftfreq -返回频率箱中心的浮动数组,以每单位采样间隔的周期为单位。

numpy.fft.fft()方法是一种获得正确频率的方法,它允许您正确地分离fft。

最好用一个例子来说明这一点:

代码语言:javascript
复制
import numpy as np
import matplotlib.pyplot as plt

#fs is sampling frequency
fs = 100.0
time = np.linspace(0,10,int(10*fs),endpoint=False)

#wave is the sum of sine wave(1Hz) and cosine wave(10 Hz)
wave = np.sin(np.pi*time)+ np.cos(np.pi*time)
#wave = np.exp(2j * np.pi * time )

plt.plot(time, wave)
plt.xlim(0,10)
plt.xlabel("time (second)")
plt.title('Original Signal in Time Domain')

plt.show()

代码语言:javascript
复制
# Compute the one-dimensional discrete Fourier Transform.

fft_wave = np.fft.fft(wave)

# Compute the Discrete Fourier Transform sample frequencies.

fft_fre = np.fft.fftfreq(n=wave.size, d=1/fs)

plt.subplot(211)
plt.plot(fft_fre, fft_wave.real, label="Real part")
plt.xlim(-50,50)
plt.ylim(-600,600)
plt.legend(loc=1)
plt.title("FFT in Frequency Domain")

plt.subplot(212)
plt.plot(fft_fre, fft_wave.imag,label="Imaginary part")
plt.legend(loc=1)
plt.xlim(-50,50)
plt.ylim(-600,600)
plt.xlabel("frequency (Hz)")

plt.show()

票数 12
EN

Stack Overflow用户

发布于 2020-01-30 16:50:45

如果“主分量”指的是5个最强的频率,您将在np.fft.fft()的结果中搜索这些值。要知道这些值属于哪个频率,您将使用np.fft.fftfreq。两者的输出都是相同长度的数组,因此您可以从np.fft.fft()将索引从np.fft.fftfreq()输入数组以获得相应的频率。

例如,假设fft的输出为A,而fftfreq的输出为B,假设A1是您的主要组件之一,则B1 = 0Hz将是主组件的频率。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59979354

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档