通常我使用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,也许这有问题吗?
答案 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')
答案 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我认为您可以解决这个问题,以防万一这种情况无法解决问题