2017-04-04 1 views
0

일반적으로 사용자 지정 기능을 데이터에 맞추기 위해 Scipy.optimize.curve_fit을 사용합니다. 이 경우의 데이터는 항상 1 차원 배열입니다.Python : NxM 배열을위한 Scipy의 curve_fit?

2 차원 배열에 대해 비슷한 기능이 있습니까?

예를 들어, 10x10 numpy 배열이 있습니다. 그런 다음 몇 가지 물건을 수행하고 10x10의 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 

자 A와 B가 장착되어야한다. 내가 지금까지 가지고 무엇

:

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

그러나 인쇄에 맞게 만

(array([ 1.]), inf) 

내가 배열의 일부 NaN을가 할, 어쩌면 문제를 이잖아 나에게 준다? 우선 까다로운 보일지 단수 xy로 좌표 변환 쌍 (x, y)g(x, y, ...) --> f(xy, ...)

:

+0

예제 데이터가 있습니까? – Cleb

+1

데이터 및 함수 출력을 병합하려 했습니까? 이렇게하면 curve_fit과 함께 작동하도록 1 차원으로 만들어야합니다. – kazemakase

+0

나는 이것이 잘 될지 모르겠다. 내 경우 NxM numpy 배열은 이미지를 나타냅니다. 만약 내가 그것을 평평하게하면, 그 가장자리에서 매우 피팅에 좋지 않은 값으로 매우 날카로운 점프를 할 것입니다. – Pythoneer

답변

2

목적은 1D 함수로서 2D 기능을 표현한다. 그러나 실제로는 아주 간단합니다. 모든 데이터 요소를 열거하면 각 좌표 쌍을 고유하게 정의하는 단일 번호가 있습니다. 맞는 함수는 단순히 원래의 좌표를 재구성하고, 계산을 수행하고 결과를 반환해야합니다. 20x10 이미지에서 2 차원 선형 그라데이션에 맞는

예 :

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로 변환했습니다. 두 번째 배열이 필요합니다. 계산서에 B라고 말하면서 1D 버전을 만들었습니다. 이제 나는 (12 * B1D) * a) ** b를 수행하고 리턴하는 def dostuff (a, b)를 가지고있다. 그러나 fit이 curve = fit (dostuff, data_X, data1D)로 수행되도록하려면 배열 ([1.]), inf) 만 반환하면됩니다. – Pythoneer

0

내가 이것에 대한 symfit을 사용하는 것이 좋습니다 것입니다, 나는 자동으로 마법의 모든 돌봐 썼다 .

symfit에서 당신은 종이에 그치지 않고 방정식을 쓰면 적합 할 수 있습니다.

나는 이런 식으로 뭔가 할 것 : 나는 아직 아직 문서에 필요한 종류의 예를 포함하지 않은 Unfortunatelly

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를 보면 당신이 그것을 알아낼 수 있다고 생각 상자 안에서 작동하지 않을 경우를 대비하여

관련 문제