【问题标题】:Python lambda function with arrays as parameters以数组为参数的 Python lambda 函数
【发布时间】:2017-05-04 00:51:27
【问题描述】:

我正在尝试定义一个包含 n 个变量的函数以适应数据集。函数如下所示。

Kelly Function

然后我想使用 scipy.optimize.leastsq 找到适合我的数据集的最佳 ai 和 bj

这是我目前的代码。

from scipy.optimize import leastsq 
import numpy as np

def kellyFunc(a, b, x): #Function to fit.
  top = 0
  bot = 0
  a = [a]
  b = [b]
  for i in range(len(a)):
    top = top + a[i]*x**(2*i)
    bot = bot + b[i]*x**(2*i)
  return(top/bot)


def fitKelly(x, y, n):
  line = lambda params, x : kellyFunc(params[0,:], params[1,:], x) #Lambda Function to minimize
  error = lambda params, x, y : line(params, x) - y #Kelly - dataset

  paramsInit = [[1 for x in range(n)] for y in range(2)] #define all ai and bi = 1 for initial guess

  paramsFin, success = leastsq(error, paramsInit, args = (x,y)) #run leastsq optimization

  #line of best fit
  xx = np.linspace(x.min(), x.max(), 100)
  yy = line(paramsFin, xx)

  return(paramsFin, xx, yy)

目前它给了我错误:
“IndexError: too many indices”,因为我用 params[0,:] 和 params[1,:] 定义了我的初始 lambda 函数。

【问题讨论】:

  • 你想用params[0,:]params[1,:] 做什么?这看起来不像是有效的 Python 列表切片语法。
  • 实际上是有效的 Python。键是元组,元组的第二个元素是切片。 NumPy 广泛使用它。
  • 我的立场是正确的!感谢您的澄清。
  • 您是否尝试重新定义 lambda?
  • 抱歉,二战我不知道你说的重新定义 lambda 是什么意思..?

标签: python lambda curve-fitting least-squares


【解决方案1】:

你的方法有一些问题让我写了一个完整的答案。

至于您的具体问题:leastsq 并不真正期望多维数组作为参数输入。文档没有说明这一点,但参数输入在传递给目标函数时会变平。您可以通过使用完整函数而不是 lambdas 来验证这一点:

from scipy.optimize import leastsq           
import numpy as np

def kellyFunc(a, b, x): #Function to fit.
  top = 0
  bot = 0
  for i in range(len(a)):
    top = top + a[i]*x**(2*i)
    bot = bot + b[i]*x**(2*i)
  return(top/bot)

def line(params,x):
  print(repr(params)) # params is 1d!
  params = params.reshape(2,-1) # need to reshape back
  return kellyFunc(params[0,:], params[1,:], x)

def error(params,x,y):
  print(repr(params)) # params is 1d!
  return line(params, x) - y # pass it on, reshape in line()

def fitKelly(x, y, n):
  #paramsInit = [[1 for x in range(n)] for y in range(2)] #define all ai and bi = 1 for initial guess
  paramsInit = np.ones((n,2)) #better
  paramsFin, success = leastsq(error, paramsInit, args = (x,y)) #run leastsq optimization

  #line of best fit
  xx = np.linspace(x.min(), x.max(), 100)
  yy = line(paramsFin, xx)

  return(paramsFin, xx, yy)

现在,如您所见,params 数组的形状是 (2*n,),而不是 (2,n)。通过重新塑造自己,您的代码(几乎)可以工作。当然,print 电话只是为了向您展示这一事实;代码运行不需要它们(并且会在每次迭代中产生一堆不必要的输出)。

查看我的其他更改,与其他错误相关:您的kellyFunc 中有a=[a]b=[b],没有任何理由。这将输入数组转换为包含数组的列表,这使得下一个循环执行的操作与您的预期非常不同。

最后,最隐秘的错误:你在fitKelly 中有输入变量名为xy,然后你使用xy 是列表推导中的循环变量。请注意,这只适用于您在 python 3 中的预期;在 python 2 中,列表推导的内部变量实际上泄漏到外部范围之外,覆盖了名为 xy 的输入变量。

【讨论】:

  • 非常感谢!是的,我弄乱了一些愚蠢的错误,哈哈,非常感谢!
  • @AdamLeinweber 我很高兴能帮上忙。如果我的回答解决了您的问题并且您对此感到满意,请考虑marking it as accepted
猜你喜欢
  • 2021-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-27
  • 2021-08-30
  • 2021-07-25
  • 2018-02-16
  • 1970-01-01
相关资源
最近更新 更多