如何实现适配x=y²的多项式拟合?解决numpy polyfit不适配问题
适配x=y²型抛物线的多项式拟合方案
原代码问题分析
你用np.polyfit(x, y, 2)拟合的是y关于x的二次函数(y = ax²+bx+c),但你的数据是x=y²——这是x作为y的单值二次函数,且单个x对应两个y值。直接拟合y(x)属于用单值函数模型匹配多值关系,必然拟合失效。
解决方案思路
- 反向拟合:拟合x关于y的二次多项式(x = ay² + by + c),因为x是y的单值函数,完全匹配你的数据分布,拟合精度会很高。
- 解二次方程:对于任意输入x,通过解二次方程
ay² + by + (c - x) = 0,得到两个y值(对应正负根),满足单个x输出两个y的需求。
完整实现代码
import numpy as np import matplotlib.pyplot as plt def get_x_vs_y_polyfit(points): # 提取y和x向量,拟合x关于y的二次多项式 y = points[:, 1] x = points[:, 0] # 拟合得到 x = a*y² + b*y + c 的系数 coeffs = np.polyfit(y, x, 2) p = np.poly1d(coeffs) # 生成拟合曲线用于可视化 y_new = np.linspace(y.min(), y.max(), 100) x_new = p(y_new) plt.scatter(x, y, label='原始数据') plt.plot(x_new, y_new, 'r-', label='拟合曲线') plt.xlim([x.min()-1, x.max()+1]) plt.legend() plt.show() return coeffs def calculate_y_from_x(coeffs, x): # 解二次方程获取两个y值 a, b, c = coeffs discriminant = b**2 - 4*a*(c - x) if discriminant < 0: return None # 无实数解的情况 sqrt_d = np.sqrt(discriminant) y1 = (-b + sqrt_d) / (2*a) y2 = (-b - sqrt_d) / (2*a) return y1, y2 def main(): arr = [] for i in range(0, 20): arr.append([pow(i,2), -i]) for i in range(0, 20): arr.append([pow(i,2), i]) arr = np.array(arr) coeffs = get_x_vs_y_polyfit(arr) target_x = 19*19 y_values = calculate_y_from_x(coeffs, target_x) print(f"x={target_x}对应的y值:{y_values}") if __name__ == "__main__": main()
代码说明
get_x_vs_y_polyfit:负责拟合x与y的二次关系,返回多项式系数,同时绘制原始数据和拟合曲线验证效果。calculate_y_from_x:输入x和拟合系数,通过求解二次方程得到两个y值,判别式小于0时返回None(无实数解)。- 运行后,针对x=361(19²)会输出接近(19.0, -19.0)的结果,完全符合预期。
内容的提问来源于stack exchange,提问作者somevisionproblems
相关产品推荐
相关产品推荐

