Fit Real-World Data with Fourier Series Using Python
This article explains Fourier series theory, demonstrates how to remove linear trends from monthly CO₂ data, and shows step‑by‑step Python code using SciPy's curve_fit to fit and predict the data with a 100‑term Fourier expansion.
Fourier Series
Any periodic function can be represented as a linear combination of sine and cosine functions with different amplitudes and phases, a concept first discovered by French mathematician Joseph Fourier.
Python Case Study
We use the Fourier series formulas to fit a real‑world dataset. Because real data contain noise, we first remove the linear trend and then fit the residual using a Fourier series with SciPy's curve_fit to estimate the coefficients.
<code>import pandas as pd
import numpy as
data = pd.read_excel('data/load_co2_monthly.xlsx', index_col=0)
</code>The first 24 rows of the monthly CO₂ data are shown in the original article (omitted here for brevity).
<code>xarray = data.index.values
yarray = data.co2.values
plt.plot(xarray, yarray)
plt.show()
</code>After plotting, a clear upward trend is observed. We remove this linear trend:
<code>k, b = np.polyfit(xarray, yarray, deg=1)
def linear(x):
return k * x + b
y_trend = linear(xarray)
plt.plot(xarray, yarray)
plt.plot(xarray, y_trend)
plt.show()
</code>Subtracting the linear component yields the detrended series:
<code>y_no_trend = yarray - linear(xarray)
plt.plot(y_no_trend)
plt.show()
</code>The detrended data exhibits a clear periodic pattern with a period of 12 months.
<code>from scipy.optimize import curve_fit
import matplotlib.pyplot as plt
import numpy as
def fourier(x, *a):
w = 2 * np.pi / 12 # period = 12
ret = 0
for deg in range(0, int(len(a) / 2) + 1):
ret += a[deg] * np.cos(deg * w * x) + a[len(a) - deg - 1] * np.sin(deg * w * x)
return ret
popt, pcov = curve_fit(fourier, xarray, y_no_trend, [1.0] * 100) # 100‑term Fourier series
y_no_trend_pred = fourier(xarray, *popt)
</code>We visualize the original detrended data against the Fourier fit:
<code>plt.figure(figsize=(10, 4))
plt.subplot(1, 2, 1)
plt.plot(xarray, y_no_trend)
plt.title('Original')
plt.subplot(1, 2, 2)
plt.plot(xarray, y_no_trend_pred)
plt.title('Fourier')
plt.show()
</code>Finally, we combine the linear trend and the Fourier‑based periodic component and compare it with the original series:
<code>plt.plot(xarray, yarray, label='original')
plt.plot(xarray, linear(xarray) + fourier(xarray, *popt), label='pred')
plt.legend()
plt.show()
</code>The combined model matches the original data closely, demonstrating that Fourier series can effectively capture periodic patterns in noisy real‑world datasets.
Reference:
Fourier Series (with Python square‑wave example) https://zhuanlan.zhihu.com/p/544218711
Model Perspective
Insights, knowledge, and enjoyment from a mathematical modeling researcher and educator. Hosted by Haihua Wang, a modeling instructor and author of "Clever Use of Chat for Mathematical Modeling", "Modeling: The Mathematics of Thinking", "Mathematical Modeling Practice: A Hands‑On Guide to Competitions", and co‑author of "Mathematical Modeling: Teaching Design and Cases".
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.