我有一个更大的代码块,它的核心是适合函数和数据。要安装的数据和函数是动态的。最近,我在整个系统中附加了一个数据点,现在curve_fit
总是返回最初的猜测(或者是一些太接近它的东西),不管我如何选择它。对于非常不同的y值和x值(前者的10组,后者的2组),会发生这种情况。
我知道选择起始值很重要,但是我以前从来没有遇到过使用默认值的问题(我的函数通常很简单),并且可以通过取消注释添加额外数据点的新代码来恢复到它工作的状态现在有人会认为,显然新代码是问题所在,但是在新的添加和实际将数据馈送到curve_fit
之间有相当多的步骤。我已经检查了curve_fit
的输入类型是否相同:np.ndarray
,在有问题的情况下,只需要长一个元素。
然而,在创建MWE时,我注意到导致这个问题的仅仅是确切的x数组当我在MWE中复制主程序的打印x向量而不是内部表示时,它完全消失了因此,我只能显示外部文件的问题:local_z.npy [150kB]
MWE:
import numpy as np
from scipy.optimize import curve_fit
values = np.array([[1.37712972, 1.58475346, 1.78578759, 1.9843099, 1.73393093],
[-0.0155715, -0.01534987, -0.00910744, -0.00189728, -1.73393093],
[1.23613934, 0.76894505, 0.18876817, 0.06376843, 1.1637315 ],
[0.8535248, 0.53093829, 0.13033993, 0.04403058, 0.80352895],
[0.51505805, 0.32039379, 0.0786534, 0.02657018, 0.48488813]])
heights = np.array([ 22.110203, 65.49054, 110.321526, 156.54034, 166.59094])
local_z = np.load('local_z.npy')
print('difference in heights', local_z - heights)
def func(z, a0, a1):
return a0 + a1*z
for v in values:
popt_non_working = curve_fit(func, local_z, v)[0]
print('not working: ', popt_non_working)
popt_working = curve_fit(func, heights, v)[0]
print('working: ', popt_working)
我对python 2.7.6、numpy 1.14.1和scipy1.0.0的输出:
$ python auxiliary/SUBLIME_fit_test.py
('difference in heights', array([-2.10693358e-07, -4.49218746e-07, -4.26269537e-07, 4.23828126e-06, 2.38281251e-06]))
/home/csag5117/venv/local/lib/python2.7/site-packages/scipy/optimize/minpack.py:785: OptimizeWarning: Covariance of the parameters could not be estimated category=OptimizeWarning)
('not working: ', array([1., 1.]))
('working: ', array([1.35420488, 0.00325281]))
('not working: ', array([1., 1.]))
('working: ', array([ 0.38896878, -0.00714073]))
('not working: ', array([1., 1.]))
('working: ', array([ 1.06301278, -0.00363439]))
('not working: ', array([1., 1.]))
('working: ', array([ 0.73398503, -0.00250946]))
('not working: ', array([1., 1.]))
('working: ', array([ 0.442922 , -0.00151433]))
如您所见,使用
heights
作为x值的版本工作正常(返回拟合参数),而使用存储的“local_z”的版本则不正常,即使两个数组之间的差异非常小。我只显示多个y值,以表明这不是百万分之一的故障,可以用正确的起始值修复这也只是一个例子,我还有一个具有相同行为的多个数据点(24而不是5)。
为了完整性起见,我添加了代码块(当我关闭此选项时,一切正常)有趣的是,在mwe中使用
local_z
忽略local_z[:-1]
中的最后一个值(这是代码块添加的值)并不能解决问题。zi_minus_dd -= 1
zf_long = np.append(out.zf, np.squeeze(data.zf[t])[z_mask_full[-1] + 1])
u_zi = np.interp(zi_minus_dd, zf_long,
np.append(out.u, np.squeeze(data.u[t])[z_mask_full[-1] + 1]))
v_zi = np.interp(zi_minus_dd, zf_long,
np.append(out.v, np.squeeze(data.v[t])[z_mask_full[-1] + 1]))
th_zi = np.interp(zi_minus_dd, zf_long,
np.append(out.th, np.squeeze(data.th[t])[z_mask_full[-1] + 1]))
zh_long = np.append(out.zh, np.squeeze(data.zh[t])[z_mask_full[-1] + 1])
uw_zi = np.interp(zi_minus_dd, zf_long,
np.append(out.uw_raw, np.squeeze(data.uw[t])[z_mask_full[-1] + 1]))
vw_zi = np.interp(zi_minus_dd, zf_long,
np.append(out.vw_raw, np.squeeze(data.vw[t])[z_mask_full[-1] + 1]))
tke_zi = np.interp(zi_minus_dd, zf_long,
np.append(out.tke, np.squeeze(data.TKE[t])[z_mask_full[-1] + 1]))
out.zf = np.append(out.zf, zi_minus_dd)
out.u = np.append(out.u, u_zi)
out.v = np.append(out.v, u_zi)
out.th = np.append(out.th, u_zi)
out.zh = np.append(out.zh, zi_minus_dd)
out.uw_raw = np.append(out.uw_raw, u_zi)
out.vw_raw = np.append(out.vw_raw, u_zi)
out.tke = np.append(out.tke, u_zi)
out.zf
和out.zh
是随后生成的向量。整个代码相当大,还依赖于netCDF文件(上面的代码片段中的
local_z
)我已经问过了,但那是为了工作代码。我非常困惑,不知道如何修复这个问题,甚至不知道如何继续调试有没有可能是copy和deepcopy之间的问题尽管我想知道这将如何通过存储阵列传输到mwe…
最佳答案
追踪这件事很有意思:-)
不是值,而是它们的类型这是一个精度问题:有效的heights
是float64,无效的local_z是float32。
我们有
In [70]: heights
Out[70]: array([ 22.110203, 65.49054 , 110.321526, 156.54034 , 166.59094 ])
In [71]: heights.dtype
Out[71]: dtype('float64')
In [72]: curve_fit(func, heights, v)[0]
Out[72]: array([1.35420488, 0.00325281])
和
In [73]: local_z
Out[73]:
array([ 22.110205, 65.49054 , 110.321526, 156.54034 , 166.59094 ],
dtype=float32)
In [74]: curve_fit(func, local_z, v)[0]
C:\Python\lib\site-packages\scipy\optimize\minpack.py:794: OptimizeWarning: Covariance of the parameters could not be estimated
category=OptimizeWarning)
Out[74]: array([1., 1.])
但如果我们愿意,我们可以让本地区工作:
In [75]: curve_fit(func, local_z.astype(np.float64), v)[0]
Out[75]: array([1.35420488, 0.00325281])
或高度失败:
In [76]: curve_fit(func, heights.astype(np.float32), v)[0]
C:\Python\lib\site-packages\scipy\optimize\minpack.py:794: OptimizeWarning: Covariance of the parameters could not be estimated
category=OptimizeWarning)
Out[76]: array([1., 1.])