fra*_*eau 5 python performance numpy curve-fitting
我必须在大量数据 (5 000 000) 上使用curve_fit numpy 函数。所以基本上我已经创建了一个二维数组。第一个维度是要执行的拟合数量,第二个维度是用于拟合的点数。
t = np.array([0 1 2 3 4])
for d in np.ndindex(data.shape[0]):
try:
popt, pcov = curve_fit(func, t, np.squeeze(data[d,:]), p0=[1000,100])
except RuntimeError:
print("Error - curve_fit failed")
Run Code Online (Sandbox Code Playgroud)
可以使用 multiprocessing 来加速整个过程,但它仍然很慢。有没有办法以“矢量化”的方式使用 curve_fit ?
曲线拟合扩展了其功能,scipy.optimize.leastsq其本身是底层 MINPACKlmdif和lmderfortran 例程的包装器。看起来多线程是不可能的,请查看此链接,其中写着:
底层 Fortran 77 例程(MINPACK lmder.f 和 lmdif.f)不可重入,因此无法释放 GIL。(因此没有机会使用线程进行并行处理。)
仍然有一个开放的票证来开发这个,但看起来它无法完成......您要么需要使用不同的库,要么在较低级别的代码中编写包装器/函数。有一些关于并行 Levenberg-Marquardt 算法实现的论文。
也许还有另一种解决方案,使用更少的数据或作为粗略估计,您可以将数据随机分成几个部分,在单独的线程(使用多处理器)上对每个部分进行曲线拟合,并在最后取系数的平均值。
加快速度的一种方法是向 curve_fit 添加一些先验知识。
如果您知道期望参数的范围,并且不需要达到第 100 个有效数字的精度,则可以大大加快计算速度。
这里有一个例子,你会适合param1和param2:
t = np.array([0 1 2 3 4])
def func(t, param1, param2):
return param1*t + param2*np.exp(t)
for d in np.ndindex(data.shape[0]):
try:
popt, pcov = curve_fit(func, t, np.squeeze(data[d,:]), p0=[1000,100],
bounds=([min_param1, min_param2],[max_param1, max_param2]),
ftol=0.5, xtol=0.5)
except RuntimeError:
print("Error - curve_fit failed")
Run Code Online (Sandbox Code Playgroud)
注意额外的关键参数bounds,ftol和xtol。您可以在此处阅读有关它们的信息。