【问题标题】:Scipy Curve Fit: "Result from function call is not a proper array of floats."Scipy Curve Fit:“函数调用的结果不是正确的浮点数组。”
【发布时间】:2021-04-11 17:07:52
【问题描述】:

我正在尝试将具有偏移量的 2D 高斯拟合到 2D 数组。该代码基于此线程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 控制台环境中运行了它,所以可能差异就是这样,不确定这种差异有多重要。

【问题讨论】:

  • 哪一行报错了?
  • @PaulH 最后一个,如果我尝试从控制台运行脚本,我将在完整的控制台输出中进行编辑。

标签: arrays python-3.x numpy scipy-optimize


【解决方案1】:

data_array(2, 2400, 2400) float64(来自添加打印)

testmap(2400, 2400) float64(再次诊断打印)

curve_fit 文档谈论 M 长度或 (k,M) 数组。

您提供 (2,N,N) 和 (N,N) 形状数组。

让我们尝试展平 N,N 维度:

在目标函数中:

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

poptpcov

[-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: 对象对于所需数组来说太深

错误信息有点模糊,虽然我隐约记得以前见过它。当输入是参差不齐的数组并且结果数组是对象 dtype 时,有时我们会遇到这样的错误。但这里只是形状问题。

过去有类似问题的SO并修复:

Scipy curve_fit for Two Dimensions Not Working - Object Too Deep?

ValueError When Performing scipy.stats test on Pandas Column Selection by Row

Fitting a 2D Gaussian function using scipy.optimize.curve_fit - ValueError and minpack.error

这只是 SO 的一个子集,具有相同的错误消息。其他scipy 函数产生它。通常问题出在 (m,1) 而不是 (N,N) 之类的形状上。我很想把它作为一个副本关闭,但我对调试细节的长回答可能很有启发性。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-14
    • 2018-07-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多