如何在Python中实现数据对数拟合?拟合异常问题求助
解决对数拟合曲线异常的问题
看起来你遇到的拟合曲线异常,大概率是两个核心原因导致的:x数据未按顺序排列,以及没有给curve_fit提供合适的初始参数猜测。我来一步步帮你解决这个问题:
问题根源分析
- 数据无序导致曲线乱跳:你的
xdata是随机顺序的,直接用原始顺序绘图时,plt.plot会按数据输入的先后连接点,而不是沿着x轴从小到大的顺序,所以曲线看起来混乱不堪。 - 对数拟合的初始值偏差:
curve_fit默认初始参数是[1,1],但你的数据范围(x是1e-7到7e-5,y是0.0018到0.0038)和这个初始值不匹配,容易让拟合算法收敛到局部最优,甚至得到不合理的参数。
修复后的完整代码
from scipy.optimize import curve_fit import numpy as np import matplotlib.pyplot as plt xdata=[9.24104360013e-06, 4.72619458107e-06, 4.03957328857e-06, 9.78301182748e-06, 1.36994566431e-05, 1.16294573409e-05, 7.70899546232e-06, 2.72587766232e-06, 2.19089955631e-06, 5.34851640035e-06, 7.84434545123e-06, 7.6524185787e-06, 1.00592536363e-05, 6.08711035578e-07, 4.08259572135e-07, 5.74424798328e-07, 6.20036326494e-07, 4.34755225756e-06, 4.72832211908e-06, 1.25156011417e-06, 1.44996714816e-05, 3.79992166335e-06, 4.45935911838e-06, 6.6307841155e-06, 2.38540191336e-06, 9.4649801666e-07, 9.11518608157e-06, 3.1944675219e-06, 5.32674287313e-06, 1.48463901861e-05, 3.41127723277e-06, 3.40027150288e-06, 3.33064781566e-06, 2.12828505238e-06, 7.22565690506e-06, 7.86527964811e-06, 2.25791582571e-06, 1.94875869207e-05, 1.54712884424e-05, 5.82300791075e-06, 9.5783833758e-06, 1.89519143607e-05, 1.03731970283e-05, 2.53090894753e-05, 9.26047056658e-06, 1.05428610146e-05, 2.89162870493e-05, 4.78624726782e-05, 1.00005855557e-05, 6.88617910928e-05] ydata=[0.00281616449359, 0.00257023004939, 0.00250030932407, 0.00284317789756, 0.00300158447316, 0.00291690879783, 0.00274898865728, 0.0023625485679, 0.0023018015629, 0.00259860025555, 0.00269155777824, 0.00265941197135, 0.0028073724168, 0.00192920496041, 0.00182900945464, 0.00191452746379, 0.00193227563253, 0.00253266811688, 0.00255961306471, 0.00212426145702, 0.00285906942634, 0.00247877245272, 0.0025348504727, 0.00269881922057, 0.00232270371493, 0.00204672286703, 0.00281306442303, 0.00241938445736, 0.00261083321385, 0.00287440363274, 0.00244324770882, 0.00244364989768, 0.00244593671433, 0.00228714406931, 0.00263301289418, 0.00269385915315, 0.0022968948347, 0.00313898537645, 0.00305650121575, 0.00265291893623, 0.00278748794063, 0.00312801724905, 0.00289450806538, 0.00313176225397, 0.00284010926578, 0.0028957865422, 0.00335438183977, 0.00360421739757, 0.00270734995952, 0.00377301191882] # 1. 对x和y按x从小到大排序,这是让曲线平滑的核心步骤 x = np.array(xdata, dtype=float) y = np.array(ydata, dtype=float) sort_indices = np.argsort(x) x_sorted = x[sort_indices] y_sorted = y[sort_indices] # 定义对数拟合函数 def func(x,a,b): return a*np.log(x)+ b # 2. 提供合理的初始参数猜测:根据数据趋势,x越大y越大,a为正;b参考y的中间值设为0.003 initial_guess = [1e-7, 0.003] popt, pcov = curve_fit(func, x_sorted, y_sorted, p0=initial_guess) # 绘图:用排序后的x绘制拟合曲线,同时保留原始散点 plt.scatter(x, y, label="Original Data", alpha=0.6) plt.plot(x_sorted, func(x_sorted, *popt), 'r-', label=f"Fitted Curve: y = {popt[0]:.2e}*ln(x) + {popt[1]:.4f}") plt.xlabel("x") plt.ylabel("y") plt.legend() plt.show() # 输出拟合参数 print(f"拟合参数a: {popt[0]:.2e}") print(f"拟合参数b: {popt[1]:.4f}")
关键改进点说明
- 数据排序:通过
np.argsort(x)获取排序索引,将x和y同步按x轴从小到大排列,这样拟合曲线会沿着x轴平滑延伸,不会出现来回跳跃的情况。 - 初始参数猜测:根据数据的增长趋势(x增大y增大)设置a为正数,结合y的取值范围设置b的初始值,能帮助
curve_fit快速收敛到最优参数,避免陷入局部最优解。
多项式拟合的补充修复
如果之前多项式拟合失败,同样是数据无序导致的绘图异常,用同样的排序方法处理后再尝试即可:
# 示例:3阶多项式拟合 z = np.polyfit(x_sorted, y_sorted, 3) p = np.poly1d(z) plt.plot(x_sorted, p(x_sorted), 'g--', label="3rd Order Polynomial") plt.legend() plt.show()
这样处理后,不管是对数拟合还是多项式拟合,结果都会正常显示。
内容的提问来源于stack exchange,提问作者Sander2711
相关产品推荐
相关产品推荐

