简体   繁体   English

根据时间序列数据创建正弦波(Python)

[英]Create a sine wave from time series data (Python)

I am trying to implement a Discrete Fourier Transform with time series data from a CSV. 我正在尝试使用来自CSV的时间序列数据实现离散傅立叶变换。 I have been able to generate a sine wave (and cosine wave) in Python with SciPy and have gotten back the magnitude and phase information I want. 我已经能够使用SciPy在Python中生成一个正弦波(和余弦波),并获得了我想要的幅度和相位信息。 However, I am struggling with real data. 但是,我正在努力处理真实数据。 My CSV looks like this, simulating events that occur Mondays at 9am. 我的CSV看起来像这样,模拟了周一上午9点​​发生的事件。

id1 ?2018-01-05T23:00:00.000Z id1?2018-01-05T23:00:00.000Z
id1 ?2018-01-08T09:20:00.000Z id1?2018-01-08T09:20:00.000Z
id1 ?2018-01-15T09:43:00.000Z id1?2018-01-15T09:43:00.000Z
id1 ?2018-01-22T09:02:00.000Z id1?2018-01-22T09:02:00.000Z
id1 ?2018-01-29T09:50:00.000Z id1?2018-01-29T09:50:00.000Z
id1 ?2018-02-05T09:47:00.000Z id1?2018-02-05T09:47:00.000Z
id1 ?2018-02-12T09:18:00.000Z id1?2018-02-12T09:18:00.000Z
id1 ?2018-02-19T09:02:04.000Z id1?2018-02-19T09:02:04.000Z
id1 ?2018-02-26T09:54:00.000Z id1?2018-02-26T09:54:00.000Z
id1 ?2018-03-05T09:12:00.000Z id1?2018-03-05T09:12:00.000Z

After getting it all cleaned up, it looks like this after binning by day (I hope to bin at the hour and minute levels eventually): 清理完所有内容后,按天进行装箱后应如下所示(我希望最终将装箱在小时和分钟的水平上):

ID..Date............Event ID..Date ............事件
id1 2018-01-08 1 id1 2018-01-08 1
id1 2018-01-09 0 id1 2018-01-09 0
id1 2018-01-10 0 id1 2018-01-10 0
id1 2018-01-11 0 id1 2018-01-11 0
id1 2018-01-12 0 id1 2018-01-12 0
id1 2018-01-13 0 id1 2018-01-13 0
id1 2018-01-14 0 id1 2018-01-14 0
id1 2018-01-15 1 id1 2018-01-15 1
id1 2018-01-16 0 id1 2018-01-16 0

...etc. ...等等。 What can I do to transform this into a sine wave? 如何将其转换为正弦波? Currently, I am creating a sine wave and running an fft like this: 目前,我正在创建一个正弦波并运行一个fft,如下所示:

A = 5 # amplitude
fc = 10 # frequency
fs = 32 * fc # sampling frequency with oversampling factor 32
t = np.arange(0, 2, 1/fs) # time array
phi = 30 # phase shift

x = A * np.cos(2 * np.pi * fc * t + phi)
fourier = fft(x)

I am able to get the phase information from this in the frequency I want which leads me to believe if I can just get a signal from my CSV file and replace that with x, then I'd be able to extract phase information from that. 我能够以所需的频率从中获取相位信息,这使我相信,如果我可以从CSV文件中获取信号并将其替换为x,那么我就可以从中提取相位信息。 My understanding is that with the binary data (the 'Event' column), magnitude information will not be helpful - is that correct? 我的理解是,对于二进制数据(“事件”列),幅度信息将无济于事-正确吗?

How do I turn this CSV file into a sine or cosine wave? 如何将此CSV文件转换为正弦或余弦波?

The current dataset that you show indeed looks nothing like a sine-wave but since all mathematically nice functions can be written as a superposition of sines and cosines, this need not be a problem. 您显示的当前数据集的确看起来并不像正弦波,但是由于所有数学上好的函数都可以写成正弦和余弦的叠加,所以这不必成问题。

More details in the docs: https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.fft.fft.html#numpy.fft.fft 在文档中了解更多详细信息: https : //docs.scipy.org/doc/numpy-1.13.0/reference/genic/numpy.fft.fft.html#numpy.fft.fft

First let us do an example: 首先让我们做一个例子:

import numpy as np
import matplotlib.pyplot as plt
T = 100
x = np.arange(0,T)
y=  np.sin(4*np.pi*x/T)+np.cos(8*np.pi*x/T)

We have thus have a superposition of a sine and cosine with frequencies twice and four-times per step x. 因此,我们有一个正弦和余弦的叠加,每步x的频率为两倍和四倍。 We now perform the Fourier Transform: 现在,我们执行傅立叶变换:

sp   = np.fft.fft(y)               # the discrete fourier transform
freq = np.fft.fftfreq(y.shape[-1]) # the accompanying frequencies

Now we can reconstruct the original function 'y' through the fourier transform as a superposition of sines and cosines and check whether we succeeded by plotting. 现在,我们可以通过傅立叶变换将原始函数“ y”重构为正弦和余弦的叠加,并通过绘图检查是否成功。

cos=np.sum([(sp[-i]+sp[i]).real/(2*T)*np.cos(2.*np.pi*freq[i]*x)\
             for i in range(len(freq))],axis=0)
sin=np.sum([(sp[-i]-sp[i]).imag/200.*np.sin(2.*np.pi*freq[i]*x)\
              for i in range(len(freq))],axis=0)

plt.plot(x, y,x,cos+sin)
plt.show()

You should see that the two curves match perfectly. 您应该看到两条曲线完美匹配。 Now your actual problem. 现在您的实际问题。

T=9
x=np.arange(0,T,0.01) # the interspacing of the datpoints for the (co)sines is 0.01
y = np.array([1,0,0,0,0,0,0,1,0]) # the input data you suggested
sp = np.fft.fft(y)
freq = np.fft.fftfreq(y.shape[-1])
cos=np.sum([(sp[-i]+sp[i]).real/(2*T)*np.cos(2.*np.pi*freq[i]*x)\
             for i in range(len(freq))],axis=0)
sin=np.sum([(sp[-i]-sp[i]).imag/200.*np.sin(2.*np.pi*freq[i]*x)\
              for i in range(len(freq))],axis=0)

plt.plot(np.arange(0,9), y,x,cos+sin)
plt.show() 

您的数据具有正弦和余弦的最佳重叠

The amplitudes of the frequencies are: 'freq[i]' are given by '(sp[-i]-sp[i]).real/(2*T)' and '(sp[-i]+sp[i]).real/(2*T)' for sines and cosines respectively. 频率幅度为:'freq [i]'由'(sp [-i] -sp [i])。real /(2 * T)'和'(sp [-i] + sp [i ])。real /(2 * T)'分别表示正弦和余弦。

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

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