scipy.optimize.curve_fit错误 - 函数的结果不是正确的浮点数组

时间:2013-09-02 19:11:26

标签: python numpy scipy

我正在尝试将2-d voigt轮廓拟合到图像的一个子部分(赋予),其中position是一个数组,在整个图像中保存相应的x和y坐标以供传递。

根据两个打印语句的输出,以下代码在我看来应该是真的应该工作。

另外,如果有人对如何更快地构建位置数组有任何快速建议,我会很感激numpy ndarrays的一些建议。我对他们来说还是有点新鲜。

import numpy as np
from scipy.special import wofz
from scipy.optimize import curve_fit
from math import pi

def voigt2d(pos,a,bx,by,Gc,Lc):
    val = np.zeros((5,5))

    for y in range(5):
        for x in range(5):
            dst = np.sqrt((pos[y][x][0]-bx)**2+(pos[y][x][1]-by)**2)

            z = ((dst+(Lc*1j))/(Gc*np.sqrt(2)))
            val[y][x] = a*wofz(z).real/(Gc*np.sqrt(2*pi))
    print val
    print val.dtype
    return val

x = np.arange(93,98)
y = np.arange(7,12)

xpos = np.array([x,x,x,x,x])
ypos = np.array([y,y,y,y,y])
ypos = np.rot90(ypos,k=3)

position = np.dstack((xpos,ypos))

impart = np.array([
    [971, 2425, 4331, 4280, 2697,],
    [1199, 3416, 6517, 4813, 2412],
    [1333, 3957, 7210, 4019, 2183],
    [1494, 4115, 4817, 3085, 1758],
    [1185, 2273, 2805, 2811, 1797]
    ],dtype=np.float64)

p,cov = curve_fit(voigt2d,position,impart)

2 个答案:

答案 0 :(得分:2)

我不确定这会为你解决,但我相信你的问题与curve_fit期望你的模型函数返回一维模型数据的事实有关。因此,最简单的方法是将自变量(position)表示为一维数组:

>>> x = np.arange(93,98)
>>> y = np.arange(7,12)
>>> position = np.transpose([np.tile(x, len(x)), np.repeat(y, len(y))])
>>> position
array([[93,  7],
       [94,  7],
       [95,  7],
       [96,  7],
       [97,  7],
       [93,  8],
       [94,  8],
       [95,  8],
       [96,  8],
       [97,  8],
       [93,  9],
       [94,  9],
       [95,  9],
       [96,  9],
       [97,  9],
       [93, 10],
       [94, 10],
       [95, 10],
       [96, 10],
       [97, 10],
       [93, 11],
       [94, 11],
       [95, 11],
       [96, 11],
       [97, 11]])

然后你必须调整模型函数以适应这个新数组。

答案 1 :(得分:2)

关于你的第二个问题,numpy中有一个方便的网格构造函数:

y,x = pos = np.mgrid[7:12,93:98]

将完全返回您手工构建的数组。 还要注意,numpy允许整个数组之间的操作而不仅仅是标量,消除了对voigt2d内部的两个循环的需要:

def voigt2d(pos,a,bx,by,Gc,Lc):
    y,x = pos
    dst = np.sqrt((x-bx)**2+(y-by)**2)
    z = ((dst+(Lc*1j))/(Gc*np.sqrt(2)))
    val = a*wofz(z).real/(Gc*np.sqrt(2*pi))

正如Bhajun所说,curve_fit需要1D数组,所以你需要压扁结果:

    return np.ravel(val)

希望有所帮助。