Python傅里叶级数拟合数据时计算y与实测Y不匹配问题求助
问题代码错误点及修正方案
核心错误梳理
- 错误1:正弦项矩阵B构造逻辑错误,
D=math.sin(2*math.pi*n*X[m])代码行放在了n的循环外,每个样本点仅计算了n=20对应的1个正弦值,导致B矩阵实际维度和预期不符 - 错误2:拟合系数未正确拆分使用,求解得到的
Cn前21项为An系数、后21项为Bn系数,原代码未做拆分,直接引用未定义的An、Bn变量计算预测值 - 错误3:预测值y的计算逻辑完全错误,n的循环被注释,且V变量未在每个样本点处重置,导致结果为累加值而非每个点的傅里叶级数计算值
- 可选优化:如果你的X数据范围不是[0,1],需要先做归一化适配傅里叶级数的默认周期1
修正后完整代码
import xlrd import math import numpy as np import matplotlib.pyplot as plt loc = ("/content/sample_data/Plot.xlsx") work_bk = xlrd.open_workbook(loc) sheet = work_bk.sheet_by_index(0) ## 提取X数据 X=np.array([]) for i in range(sheet.nrows): X=np.append(X,sheet.cell_value(i, 0)) # 若X范围不是[0,1],放开下面注释做归一化 # X = (X - X.min())/(X.max() - X.min()) X= X.reshape(-1,1) sample_num = X.shape[0] ## 提取Y数据 Y=np.array([]) for j in range(sheet.nrows): Y=np.append(Y,sheet.cell_value(j, 1)) Y= Y.reshape(-1,1) ## 构造傅里叶基矩阵 order = 20 A = np.zeros((sample_num, order+1)) B = np.zeros((sample_num, order+1)) for m in range(sample_num): for n in range(order+1): A[m, n] = math.cos(2*math.pi*n*X[m]) B[m, n] = math.sin(2*math.pi*n*X[m]) Z = np.hstack((A,B)) # 求解系数 Cn = np.linalg.pinv(Z).dot(Y) An = Cn[:order+1] Bn = Cn[order+1:] ## 计算预测值y y = np.zeros_like(Y) for m in range(sample_num): val = 0 for n in range(order+1): val += An[n]*math.cos(2*math.pi*n*X[m]) + Bn[n]*math.sin(2*math.pi*n*X[m]) y[m] = val ## 绘图对比 plt.plot(X, Y, label='实测值') plt.plot(X, y, label='拟合值') plt.legend() plt.show()
内容的提问来源于stack exchange,提问作者Ahmed Abrar Shayor
相关产品推荐
相关产品推荐

