2017-04-04 3 views
0

通常、私はScipy.optimize.curve_fitを使用してカスタム関数をデータに合わせます。 この場合のデータは、常に1次元配列でした。Python:NxM配列のScipyのcurve_fit?

2次元配列にも同様の機能がありますか?

たとえば、私は10x10個の配列を持っています。次に、私はいくつかのものを行い、10×10のnumpy配列を作成する関数を持っています。その結果得られる10x10配列が入力配列に最もよくフィットするように関数に適合させたいと思います。そのNEWDATAデータにできるだけ近くなるよう

多分例は良好である:)今

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 

及びbは、取り付けられなければなりません。私がこれまでに得たもの

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

しかし、印刷フィットのみ

(array([ 1.]), inf) 

私は配列内のいくつかのNaNを持っている、多分問題のthats私に与えますか?最初にトリッキーに見えるかもしれません単数xyに座標ペア(x, y)変換g(x, y, ...) --> f(xy, ...)

+0

サンプルデータがありますか? – Cleb

+1

データとその関数の出力を平坦化しようとしましたか?これにより、curve_fitで動作するようにそれらを1次元にする必要があります。 – kazemakase

+0

これはうまくいくとは思えません。私の場合、NxMのnumpy配列はイメージを表します。私がそれを平坦化すると、エッジで非常に急なジャンプがあるかもしれませんが、それはフィッティングに悪いかもしれません。 – Pythoneer

答えて

2

目的は1D関数としての2D機能を発現させることです。しかし、それは実際には非常に簡単です。すべてのデータポイントを列挙するだけで、各座標ペアを一意に定義する単一の番号があります。フィットされた関数は、単に元の座標を再構成し、計算して結果を返さなければなりません。 20×10の画像では、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

+0

それは本当に有望に見えます、私はそれを試してみましょう。どうも! – Pythoneer

+0

ええと、私はこの機能の座標の分離を理解できません。変数aとbに依存する関数があり、実際の計算は(array * a)** bのようなものです。どのように各座標ごとにこれを行うのですか?まだ(i * a)** b +(j * a)** b? – Pythoneer

+0

これまでのところ、入力データを配列として持っていて、np.ravel()を使って1Dに変換しました。私は2番目の配列が必要です、私は1Dバージョンを作成した私の計算でBと言うことができます。今私は(12 * B1D)* a)** bを行い、それを返すdef dostuff(a、b)を持っています。しかし、私がfit = curve_fit(dostuff、data_X、data1D)を使って適合をさせると、それは返すだけです(array([1.])、inf)。 – Pythoneer

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を見れば、私はあなたがそれを把握することができると思いますがこれは箱の外で動作しない場合。

関連する問題