<jupyter_start><jupyter_text>Analyzing the frequency components of a signal with a Fast Fourier Transform Fast Fourier Transforms (FFT) are a fast way to find dominant frequencies in any signal.Lets start with the standard imports.<jupyter_code>import datetime
import numpy as np
import scipy as sp
import scipy.fftpack
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline<jupyter_output><empty_output><jupyter_text>Now lets look at some weather data to see if we can find a dominant seasonal pattern.<jupyter_code>df0 = pd.read_csv('data/weather.csv',
                  na_values=(-9999),
                  parse_dates=['DATE'])
df = df0[df0['DATE'] >= '19940101']
df.head()
df_avg = df.dropna().groupby('DATE').mean()
df_avg.head()
date = pd.to_datetime(df_avg.index)
temp = (df_avg['TMAX'] + df_avg['TMIN']) / 20.
N = len(temp)<jupyter_output><empty_output><jupyter_text>If we plot the temperature results for the last several years, we see a pattern.<jupyter_code>fig, ax = plt.subplots(1, 1, figsize=(6, 3))
temp.plot(ax=ax, lw=.5)
ax.set_ylim(-10, 40)
ax.set_xlabel('Date')
ax.set_ylabel('Mean temperature')<jupyter_output><empty_output><jupyter_text>Now lets apply the FFT to calculate the frequency of that pattern.  Does it match our expected result of peaks in temperature roughly each year?<jupyter_code>temp_fft = sp.fftpack.fft(temp)
temp_psd = np.abs(temp_fft) ** 2
fftfreq = sp.fftpack.fftfreq(len(temp_psd), 1. / 365)
i = fftfreq > 0
fig, ax = plt.subplots(1, 1, figsize=(8, 4))
ax.plot(fftfreq[i], 10 * np.log10(temp_psd[i]))
ax.set_xlim(0, 5)
ax.set_xlabel('Frequency (1/year)')
ax.set_ylabel('PSD (dB)')<jupyter_output><empty_output><jupyter_text>Sure enough there is a dominant frequency at 1.  Therefore we can conclude that there is a perodicity of the data when we look at the annual temperature, and the period is almost exactly 1 year.Of course we are not suprised.  We know this to be true.Can you think of other things that might reveal an underlying structure with a perodicity?Using these results, we can apply the period of 1 year to plot a "smooth" line of mean temperature, overlayed on the actual temperature.  From this we could do futher analysis, but we will stop here.<jupyter_code>temp_fft_bis = temp_fft.copy()
temp_fft_bis[np.abs(fftfreq) > 1.1] = 0
temp_slow = np.real(sp.fftpack.ifft(temp_fft_bis))
fig, ax = plt.subplots(1, 1, figsize=(6, 3))
temp.plot(ax=ax, lw=.5)
ax.plot_date(date, temp_slow, '-')
ax.set_xlim(datetime.date(1994, 1, 1),
            datetime.date(2000, 1, 1))
ax.set_ylim(-10, 40)
ax.set_xlabel('Date')
ax.set_ylabel('Mean temperature')<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.11711371363808085, 'fraction_numerical': 0.026445032111824706, 'mean_word_length': 5.201405152224824, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 24, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '5', 'dir': 'jupyter-structured-clean-dedup', 'id': '478289', 'license': 'MIT', 'n_tokens_mistral': 1000, 'n_tokens_neox': 932, 'n_words': 285, 'path': 'notebooks/D6_L2_Filtering/06_signal_fourier.ipynb', 'repo_name': 'highrain2/myTestProjs', 'size': '2647'}