【问题标题】:Using a Function Defined In a Function使用函数中定义的函数
【发布时间】:2019-09-07 03:12:02
【问题描述】:

我正在尝试在我已经编写的函数中使用一个函数,它适用于 list comprehension 和部分函数,​​但不适用于 lambda 函数。

所以我的功能是:

import numpy as np
from scipy.optimize import minimize
from _functools import partial
from sklearn.metrics import mean_squared_error

arpdau = np.random.randint(0,100,15)

def fitARPDAU(arpdau, max_cohortday, method, par=None):

  valid = {'log', 'power', 'all'}
  if method not in valid:
      raise ValueError("results: method must be one of %r." % valid)

  values = par

  if method == 'log':

    if values == None:
      a = 1
      b = 0
      c = 1
      values = [a, b, c]
      bounds = [(1e-10, None), (1e-10, None), (None, None)]

    def getArpdauFunction(x, values):
      return values[0] * np.log(x + values[1]) + values[2]
  elif method == 'power':

    if values == None:
      a = 1
      b = 0
      c = .5
      d = 0
      values = [a, b, c, d]
      bounds = [(1e-10, None), (None, None), (1e-10, 1), (None, None)]


    def getArpdauFunction(x, values):
      return values[0] * (x + values[1]) ** values[2]+ values[3]

  elif method == 'all':

    log_loss = fitARPDAU(arpdau, max_cohortday, method='log', par=par)
    power_loss = fitARPDAU(arpdau, max_cohortday, method='power', par=par)

    combined_models = [log_loss, power_loss]
    losses = map(lambda x: x[0].fun, combined_models)
    return combined_models[np.argmin(losses)]

  def getLossOptim(values):

    # import ipdb; ipdb.set_trace()
    # arpdau_pred = [getArpdauFunction(x, values) for x in range(max_cohortday)]
    arpdau_pred_1 = map(lambda x: getArpdauFunction(x, values), range(max_cohortday))
    # arpdau_pred_2 = partial(getArpdauFunction, values=values)(range(271))
    return mean_squared_error(arpdau, arpdau_pred_1[:len(arpdau)])

  result = minimize(getLossOptim, values, method='L-BFGS-B', bounds=bounds)

  return result, [getArpdauFunction(x, result.x) for x in range(max_cohortday)], result.x, method, getArpdauFunction

print fitARPDAU(arpdau, 100, method='all', par=None)

在 getLossOptim 中是否有任何理由可以使部分和列表理解起作用,但 lambda 函数却不起作用?

lambda 函数返回

NameError: global name 'getArpdauFunction' is not defined

谢谢!


【问题讨论】:

  • “不起作用”是什么意思?
  • 在另一个函数中定义的函数没有什么特别之处,出现此错误的原因是该函数可能未定义。例如,如果method 既不是'log' 也不是'power',那么getArpdauFunction 是未定义的。
  • 确实,getArpdauFunction() 绑定到 if method = 'all' 是什么?
  • 您发布的代码没有主程序。您还没有跟踪代码以显示 getArpdauFunction 确实是在执行期间定义的。
  • 顺便说一下,在 python 中,power 是**^ 是异或。

标签: python numpy scipy


【解决方案1】:

这与在另一个函数内部定义的函数无关。如果method 不是'log''power',则永远不会定义getArpdauFunction()

您可能应该为所有内容定义它,然后在方法为 'log''power' 时重载它。

这与您的问题无关,但您也不应该使用if x == None。因为None是一个单例,所以使用if x is None更高效和pythonic

【讨论】:

    【解决方案2】:

    正如我在评论中所说,您的问题与在另一个函数中定义的函数无关。您收到错误的原因是该函数有时未定义;如果method 既不是'log' 也不是'power',则永远不会定义getArpdauFunction()

    这很容易解决。我现在能看到的最简洁的方法是声明几个函数,然后动态选择一个:

    def identity(x): return x
    def pp(x): return x+1
    def mm(x): return x-1
    
    functions = {
      "++": pp,
      "--": mm
    }
    
    default_function = identity
    
    print(functions.get("++", default_function)(2)) # 3
    print(functions.get("--", default_function)(2)) # 1
    print(functions.get("non existing function name", default_function)(2)) # 2
    

    如果你的函数很短(如本例,那么你可以直接写:

    functions = {
      "++": lambda x: x+1,
      "--": lambda x: x-1
    }
    

    【讨论】:

      猜你喜欢
      • 2016-08-17
      • 1970-01-01
      • 2016-06-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-09-23
      • 1970-01-01
      相关资源
      最近更新 更多