2012-04-15 4 views
2

Я пытаюсь установить функцию, которая принимает в качестве входных 2 независимых переменных x, y и 3 параметров, которые будут найдены a, b, c. Это мой тестовый код:Передача аргументов функции для установки

import numpy as np 
from scipy.optimize import curve_fit 

def func(x,y, a, b, c): 
    return a*np.exp(-b*(x+y)) + c  

y= x = np.linspace(0,4,50) 
z = func(x,y, 2.5, 1.3, 0.5) #works ok 
#generate data to be fitted 
zn = z + 0.2*np.random.normal(size=len(x)) 
popt, pcov = curve_fit(func, x,y, zn) #<--------Problem here!!!!! 

Но я получаю сообщение об ошибке: "Func() принимает ровно 5 аргументов (51 дан)". Как правильно передать аргументы x, y?

+0

Что говорит о 'curve_fit' документации о параметре' func'? Очевидно, он пытается назвать это 51 параметром, поэтому, возможно, вам стоит перечитать документацию. – Wes

ответ

6

Взгляд на documentation of scipy.optimize.curve_fit() все, что нужно. Прототип

scipy.optimize.curve_fit(f, xdata, ydata, p0=None, sigma=None, **kw) 

документации говорится curve_fit() вызывается с целевой функцией в качестве первого аргумента, независимой переменной (ы) в качестве второго аргумента, зависимой переменной в качестве третьего аргумента анс значений начальных для параметров как четвертый аргумент. Вы пытались вызвать функцию совершенно по-другому, поэтому неудивительно, что она не работает. В частности, вы передали zn как параметр p0 - поэтому функция вызывалась с таким количеством параметров.

документация также описывает, как целевая функция называется:

f : callable
The model function, f(x, ...) . It must take the independent variable as the first argument and the parameters to fit as separate remaining arguments.

xdata : An N -length sequence or an (k,N) -shaped array
for functions with k predictors. The independent variable where the data is measured.

Вы пытаетесь использования для разделения аргументов для зависимых переменных, в то время как он должен быть один массив аргументов. Вот исправленный код:

def func(x, a, b, c): 
    return a * np.exp(-b * (x[0] + x[1])) + c  

N = 50 
x = np.linspace(0,4,50) 
x = numpy.array([x, x])   # Combine your `x` and `y` to a single 
           # (2, N)-array 
z = func(x, 2.5, 1.3, 0.5) 
zn = z + 0.2 * np.random.normal(size=x.shape[1]) 
popt, pcov = curve_fit(func, x, zn) 
+0

спасибо большое, проблема решена! – elyase

0

Попробуйте пройти первые два параметра массива в func как кортеж и изменить func принять кортеж параметров

Обычно это ожидается curvefit бы принять х и у параметра func(x) в качестве входных данных, чтобы соответствовать кривая. Как ни странно, в вашем примере, поскольку ваш параметр x - это не одно значение, а два значения (не знаете почему), вы должны изменить свою функцию, чтобы принять x в качестве единственного параметра и расширять его внутри.

Вообще говоря, трехмерная подгонка кривой должна обрабатываться иначе, чем вы пытаетесь достичь. Вы можете взглянуть на следующее сообщение SO, которое попыталось установить трехмерный разброс с линией.

>>> def func((x,y), a, b, c): 
    return a*np.exp(-b*(x+y)) + c 

>>> y= x = np.linspace(0,4,50) 
>>> z = func((x,y), 2.5, 1.3, 0.5) #works ok 
>>> zn = z + 0.2*np.random.normal(size=len(x)) 
>>> popt, pcov = curve_fit(func, (x,y), zn) 
Смежные вопросы