Python:Scipy的NxM阵列的curve_fit?

时间:2017-04-04 08:33:39

标签: python arrays numpy scipy curve-fitting

通常我使用Scipy.optimize.curve_fit来使自定义函数适合数据。 在这种情况下,数据始终是一维数组。

二维数组是否有类似的功能?

所以,例如,我有一个10x10 numpy数组。然后我有一个函数执行一些操作并创建一个10x10 numpy数组,我想要适合该函数,以便生成的10x10数组最适合输入数组。

也许一个例子更好:)

data = pyfits.getdata('data.fits')  #fits is an image format, this gives me a NxM numpy array
mod1 = pyfits.getdata('mod1.fits')
mod2 = pyfits.getdata('mod2.fits')    
mod3 = pyfits.getdata('mod3.fits')

mod1_1D = numpy.ravel(mod1)
mod2_1D = numpy.ravel(mod2)    
mod3_1D = numpy.ravel(mod3)
def dostuff(a,b):    #originaly this is a function for 2D arrays
    newdata = (mod1_1D*12)+(mod2_1D)**a - mod3_1D/b
    return newdata

现在应该安装a和b,以便newdata尽可能接近数据。

到目前为止我得到了什么:

data1D = numpy.ravel(data)
data_X = numpy.arange(data1D.size)
fit = curve_fit(dostuff,data_X,data1D)

但是打印适合只给我

(array([ 1.]), inf)

我在数组中确实有一些nans,也许这有问题吗?

2 个答案:

答案 0 :(得分:2)

目标是将2D功能表达为一维功能:g(x, y, ...) --> f(xy, ...)

首先将坐标对(x, y)转换为单个数字xy似乎很棘手。但它实际上非常简单。只需枚举所有数据点,您就有一个唯一定义每个坐标对的数字。拟合函数只需重建原始坐标,进行计算并返回结果。

在20x10图像中拟合2D线性渐变的示例:

import scipy as sp
import numpy as np
import matplotlib.pyplot as plt

n, m = 10, 20

# noisy example data
x = np.arange(m).reshape(1, m)
y = np.arange(n).reshape(n, 1)
z = x + y * 2 + np.random.randn(n, m) * 3

def f(xy, a, b):
    i = xy // m  # reconstruct y coordinates
    j = xy % m  # reconstruct x coordinates
    out = i * a + j * b
    return out

xy = np.arange(z.size)  # 0 is the top left pixel and 199 is the top right pixel
res = sp.optimize.curve_fit(f, xy, np.ravel(z))

z_est = f(xy, *res[0])
z_est2d = z_est.reshape(n, m)


plt.subplot(2, 1, 1)
plt.plot(np.ravel(z), label='original')
plt.plot(z_est, label='fitted')
plt.legend()

plt.subplot(2, 2, 3)
plt.imshow(z)
plt.xlabel('original')

plt.subplot(2, 2, 4)
plt.imshow(z_est2d)
plt.xlabel('fitted')

enter image description here

答案 1 :(得分:0)

我建议使用symfit,我写这篇文章是为了自动处理所有魔法。

symfit中,您可以像在纸上一样编写等式,然后就可以运行拟合。

我会做这样的事情:

from symfit import parameters, variables, Fit

# Assuming all this data is in the form of NxM arrays
data = pyfits.getdata('data.fits')
mod1 = pyfits.getdata('mod1.fits')
mod2 = pyfits.getdata('mod2.fits')    
mod3 = pyfits.getdata('mod3.fits')

a, b = parameters('a, b')
x, y, z, u = variables('x, y, z, u')
model = {u: (x * 12) + y**a - z / b}

fit = Fit(model, x=mod1, y=mod2, z=mod3, u=data)
fit_result = fit.execute()
print(fit_result)

不幸的是,我还没有在文档中包含您需要的那种示例,但是如果您只看docs我认为您可以解决这个问题,以防万一这种情况无法解决问题