Scipy 曲线拟合:"Result from function call is not a proper array of floats."
Scipy Curve Fit: "Result from function call is not a proper array of floats."
我正在尝试将具有偏移量的二维高斯分布拟合到二维数组。该代码基于此线程 here(当我使用 Python3 时,它是为 Python2 编写的,因此需要进行一些更改以使其在某种程度上 运行):
import numpy as np
import scipy.optimize as opt
n_pixels = 2400
def twoD_Gaussian(data_list, amplitude, xo, yo, sigma_x, sigma_y, offset):
x = data_list[0]
y = data_list[1]
theta = 0 # don't care about theta for the moment but want to leave the option in
a = (np.cos(theta)**2)/(2*sigma_x**2) + (np.sin(theta)**2)/(2*sigma_y**2)
b = -(np.sin(2*theta))/(4*sigma_x**2) + (np.sin(2*theta))/(4*sigma_y**2)
c = (np.sin(theta)**2)/(2*sigma_x**2) + (np.cos(theta)**2)/(2*sigma_y**2)
g = offset + amplitude*np.exp( - (a*((x-xo)**2) + 2*b*(x-xo)*(y-yo) + c*((y-yo)**2)))
return g
x = np.linspace(1, n_pixels, n_pixels) #starting with 1 because proper data is from a fits file
y = np.linspace(1, n_pixels, n_pixels)
x, y = np.meshgrid(x,y)
amp = -3
x0, y0 = n_pixels/2, n_pixels/2
sigma_x, sigma_y = 100, 100
offset = -1
initial_guess = np.asarray([amp, x0, y0, sigma_x, sigma_y, offset])
data_array = np.asarray([x, y])
testmap = twoD_Gaussian(data_array, initial_guess[0], initial_guess[1], initial_guess[2], initial_guess[3], initial_guess[4], initial_guess[5])
popt, pcov = opt.curve_fit(twoD_Gaussian, data_array, testmap, p0=initial_guess)
但是,我首先得到一个值错误:
ValueError: object too deep for desired array
追溯然后追溯到:
error: Result from function call is not a proper array of floats.
根据我在其他线程中的理解,这与参数的某些部分没有被正确定义为数组有关,但是例如作为一个符号对象,我不明白,因为输出测试图(按预期工作)实际上是一个 numpy 数组,并且 curve_fit 的所有输入也是一个 numpy 数组或函数本身。确切的问题是什么,我该如何解决?
编辑:如果我尝试从控制台运行它的完整错误是:
ValueError: object too deep for desired array
Traceback (most recent call last):
File "fit-2dgauss.py", line 41, in <module>
popt, pcov = opt.curve_fit(twoD_Gaussian, data_array, test, p0=initial_guess)
File "/users/drhiem/.local/lib/python3.6/site-packages/scipy/optimize/minpack.py", line 784, in curve_fit
res = leastsq(func, p0, Dfun=jac, full_output=1, **kwargs)
File "/users/drhiem/.local/lib/python3.6/site-packages/scipy/optimize/minpack.py", line 423, in leastsq
gtol, maxfev, epsfcn, factor, diag)
minpack.error: Result from function call is not a proper array of floats.
我刚刚注意到,现在是“minpack.error”,而不是“错误”。我 运行 出于测试目的,事先在 ipython 控制台环境中进行了此操作,所以可能差异在于此,不确定这种差异有多重要。
data_array
是 (2, 2400, 2400)
float64
(来自添加的打印)
testmap
是 (2400, 2400)
float64
(再次是诊断打印)
curve_fit
文档讨论 M 长度或 (k,M) 数组。
您正在提供 (2,N,N) 和 (N,N) 形状数组。
让我们尝试展平 N,N 维度:
在objective函数中:
def twoD_Gaussian(data_list, amplitude, xo, yo, sigma_x, sigma_y, offset):
x = data_list[0]
y = data_list[1]
x = x.reshape(2400,2400)
y = y.reshape(2400,2400)
theta = 0 # don't care about theta for the moment but want to leave the option in
a = (np.cos(theta)**2)/(2*sigma_x**2) + (np.sin(theta)**2)/(2*sigma_y**2)
b = -(np.sin(2*theta))/(4*sigma_x**2) + (np.sin(2*theta))/(4*sigma_y**2)
c = (np.sin(theta)**2)/(2*sigma_x**2) + (np.cos(theta)**2)/(2*sigma_y**2)
g = offset + amplitude*np.exp( - (a*((x-xo)**2) + 2*b*(x-xo)*(y-yo) + c*((y-yo)**2)))
return g.ravel()
和
并在通话中:
testmap = twoD_Gaussian(data_array.reshape(2,-1), initial_guess[0], initial_guess[1], initial_guess[2], initial_guess[3], initial_guess[4], initial_guess[5])
# shape (5760000,) float64
print(type(testmap),testmap.shape, testmap.dtype)
popt, pcov = opt.curve_fit(twoD_Gaussian, data_array.reshape(2,-1), testmap, p0=initial_guess)
它运行:
1624:~/mypy$ python3 stack65587542.py
(2, 2400, 2400) float64
<class 'numpy.ndarray'> (5760000,) float64
popt
和 pcov
:
[-3.0e+00 1.2e+03 1.2e+03 1.0e+02 1.0e+02 -1.0e+00]
[[ 0. -0. -0. 0. 0. -0.]
[-0. 0. -0. -0. -0. -0.]
[-0. -0. 0. -0. -0. -0.]
[ 0. -0. -0. 0. 0. 0.]
[ 0. -0. -0. 0. 0. 0.]
[-0. -0. -0. 0. 0. 0.]]
popt
值与预期的 initial_guess
相同,具有确切的 testmap
。
所以基本问题是您没有认真对待文档规范。那
ValueError: object too deep for desired array
错误信息有点晦涩,虽然我依稀记得以前见过它。当输入是参差不齐的数组并且结果数组是对象 dtype 时,有时我们会遇到这样的错误。但这里只是形状问题。
过去有类似问题并修复的 SO:
Scipy curve_fit for Two Dimensions Not Working - Object Too Deep?
Fitting a 2D Gaussian function using scipy.optimize.curve_fit - ValueError and minpack.error
这只是具有相同错误消息的 SO 的一个子集。其他 scipy
函数产生它。通常问题出在像 (m,1) 而不是 (N,N) 这样的形状上。我很想将其作为重复项关闭,但我对调试细节的长篇回答可能具有指导意义。
我正在尝试将具有偏移量的二维高斯分布拟合到二维数组。该代码基于此线程 here(当我使用 Python3 时,它是为 Python2 编写的,因此需要进行一些更改以使其在某种程度上 运行):
import numpy as np
import scipy.optimize as opt
n_pixels = 2400
def twoD_Gaussian(data_list, amplitude, xo, yo, sigma_x, sigma_y, offset):
x = data_list[0]
y = data_list[1]
theta = 0 # don't care about theta for the moment but want to leave the option in
a = (np.cos(theta)**2)/(2*sigma_x**2) + (np.sin(theta)**2)/(2*sigma_y**2)
b = -(np.sin(2*theta))/(4*sigma_x**2) + (np.sin(2*theta))/(4*sigma_y**2)
c = (np.sin(theta)**2)/(2*sigma_x**2) + (np.cos(theta)**2)/(2*sigma_y**2)
g = offset + amplitude*np.exp( - (a*((x-xo)**2) + 2*b*(x-xo)*(y-yo) + c*((y-yo)**2)))
return g
x = np.linspace(1, n_pixels, n_pixels) #starting with 1 because proper data is from a fits file
y = np.linspace(1, n_pixels, n_pixels)
x, y = np.meshgrid(x,y)
amp = -3
x0, y0 = n_pixels/2, n_pixels/2
sigma_x, sigma_y = 100, 100
offset = -1
initial_guess = np.asarray([amp, x0, y0, sigma_x, sigma_y, offset])
data_array = np.asarray([x, y])
testmap = twoD_Gaussian(data_array, initial_guess[0], initial_guess[1], initial_guess[2], initial_guess[3], initial_guess[4], initial_guess[5])
popt, pcov = opt.curve_fit(twoD_Gaussian, data_array, testmap, p0=initial_guess)
但是,我首先得到一个值错误:
ValueError: object too deep for desired array
追溯然后追溯到:
error: Result from function call is not a proper array of floats.
根据我在其他线程中的理解,这与参数的某些部分没有被正确定义为数组有关,但是例如作为一个符号对象,我不明白,因为输出测试图(按预期工作)实际上是一个 numpy 数组,并且 curve_fit 的所有输入也是一个 numpy 数组或函数本身。确切的问题是什么,我该如何解决?
编辑:如果我尝试从控制台运行它的完整错误是:
ValueError: object too deep for desired array
Traceback (most recent call last):
File "fit-2dgauss.py", line 41, in <module>
popt, pcov = opt.curve_fit(twoD_Gaussian, data_array, test, p0=initial_guess)
File "/users/drhiem/.local/lib/python3.6/site-packages/scipy/optimize/minpack.py", line 784, in curve_fit
res = leastsq(func, p0, Dfun=jac, full_output=1, **kwargs)
File "/users/drhiem/.local/lib/python3.6/site-packages/scipy/optimize/minpack.py", line 423, in leastsq
gtol, maxfev, epsfcn, factor, diag)
minpack.error: Result from function call is not a proper array of floats.
我刚刚注意到,现在是“minpack.error”,而不是“错误”。我 运行 出于测试目的,事先在 ipython 控制台环境中进行了此操作,所以可能差异在于此,不确定这种差异有多重要。
data_array
是 (2, 2400, 2400)
float64
(来自添加的打印)
testmap
是 (2400, 2400)
float64
(再次是诊断打印)
curve_fit
文档讨论 M 长度或 (k,M) 数组。
您正在提供 (2,N,N) 和 (N,N) 形状数组。
让我们尝试展平 N,N 维度:
在objective函数中:
def twoD_Gaussian(data_list, amplitude, xo, yo, sigma_x, sigma_y, offset):
x = data_list[0]
y = data_list[1]
x = x.reshape(2400,2400)
y = y.reshape(2400,2400)
theta = 0 # don't care about theta for the moment but want to leave the option in
a = (np.cos(theta)**2)/(2*sigma_x**2) + (np.sin(theta)**2)/(2*sigma_y**2)
b = -(np.sin(2*theta))/(4*sigma_x**2) + (np.sin(2*theta))/(4*sigma_y**2)
c = (np.sin(theta)**2)/(2*sigma_x**2) + (np.cos(theta)**2)/(2*sigma_y**2)
g = offset + amplitude*np.exp( - (a*((x-xo)**2) + 2*b*(x-xo)*(y-yo) + c*((y-yo)**2)))
return g.ravel()
和
并在通话中:
testmap = twoD_Gaussian(data_array.reshape(2,-1), initial_guess[0], initial_guess[1], initial_guess[2], initial_guess[3], initial_guess[4], initial_guess[5])
# shape (5760000,) float64
print(type(testmap),testmap.shape, testmap.dtype)
popt, pcov = opt.curve_fit(twoD_Gaussian, data_array.reshape(2,-1), testmap, p0=initial_guess)
它运行:
1624:~/mypy$ python3 stack65587542.py
(2, 2400, 2400) float64
<class 'numpy.ndarray'> (5760000,) float64
popt
和 pcov
:
[-3.0e+00 1.2e+03 1.2e+03 1.0e+02 1.0e+02 -1.0e+00]
[[ 0. -0. -0. 0. 0. -0.]
[-0. 0. -0. -0. -0. -0.]
[-0. -0. 0. -0. -0. -0.]
[ 0. -0. -0. 0. 0. 0.]
[ 0. -0. -0. 0. 0. 0.]
[-0. -0. -0. 0. 0. 0.]]
popt
值与预期的 initial_guess
相同,具有确切的 testmap
。
所以基本问题是您没有认真对待文档规范。那
ValueError: object too deep for desired array
错误信息有点晦涩,虽然我依稀记得以前见过它。当输入是参差不齐的数组并且结果数组是对象 dtype 时,有时我们会遇到这样的错误。但这里只是形状问题。
过去有类似问题并修复的 SO:
Scipy curve_fit for Two Dimensions Not Working - Object Too Deep?
Fitting a 2D Gaussian function using scipy.optimize.curve_fit - ValueError and minpack.error
这只是具有相同错误消息的 SO 的一个子集。其他 scipy
函数产生它。通常问题出在像 (m,1) 而不是 (N,N) 这样的形状上。我很想将其作为重复项关闭,但我对调试细节的长篇回答可能具有指导意义。