【问题标题】:How to produce a "Callable function"如何生成“可调用函数”
【发布时间】:2015-02-19 22:20:29
【问题描述】:

我目前正在编写一个名为 f_from_data 的 python 定义,它在一条线上使用插值查找点到目前为止我已经写了这个:

def f_from_data(xs, ys, x):
    xfine = np.linspace(min(xs), max(xs), 10000)
    y0 = inter.interp1d(xs, ys, kind = 'linear')
    ans = (y0(xfine))[numpy.searchsorted(xfine, x)]
    ans =  round(ans,2)
    return ans

这给了我我想要的东西,所以我可以输入:

f = f_from_data([3, 4, 6], [0, 1, 2])
print f(3)
>>>0.0

我该怎么做呢?我环顾四周,但似乎找不到任何东西,因为我认为这真的很微不足道,但我只是错过了一些东西。

【问题讨论】:

标签: python numpy callable


【解决方案1】:

使用functools.partial

from functools import partial

f = partial(f_from_data, [3, 4, 6], [0, 1, 2])

partial 将创建一个已设置前 2 个参数的可调用对象。

【讨论】:

    【解决方案2】:

    interpolate.interp1d 返回一个可调用对象:

    import scipy.interpolate as interpolate
    
    f_from_data = interpolate.interp1d
    f = f_from_data([3, 4, 6], [0, 1, 2])
    print(f(3))
    

    产量

    0.0
    

    由于f_from_data 可以分配给interpolate.interp1d,您可能根本不需要f_from_data。现在,确实这不会将 x 范围切割成 10000 个网格点,并使用 searchsorted 将 x 值捕捉到附近的网格点,但总的来说,您无论如何都不想这样做,因为 interp1d 给出没有它,你会得到更好的线性插值。

    【讨论】:

      【解决方案3】:

      也许是这样的?

      def f_from_data(xs, ys):
          def interpolate(x):
             xfine = np.linspace(min(xs), max(xs), 10000)
             y0 = inter.interp1d(xs, ys, kind = 'linear')
             ans = (y0(xfine))[numpy.searchsorted(xfine, x)]
             ans =  round(ans,2)
             return ans
          return interpolate
      

      警告 - 我不太了解 matplotlib,无法说出代码是否正确。

      【讨论】:

        【解决方案4】:

        如果你想要的很简单,这里有一个简单的解决方案

        >>> f = lambda x: f_from_data([3, 4, 6], [0, 1, 2], x)
        >>> print f(3)
        0.0
        >>> 
        

        如果你不喜欢lambda

        >>> def f(x): return f_from_data([3, 4, 6], [0, 1, 2], x)
        

        在这两种情况下,当您定义辅助函数时,您必须确保 f_from_data 在范围内。

        【讨论】:

          【解决方案5】:

          更通用的方法是使用__call__ 方法创建一个类,如下所示:

          class f_from_data(object):
              def __init__(self, xs, ys):
                  self.xfine = np.linspace(min(xs), max(xs), 10000)
                  self.y0 = inter.interp1d(xs, ys, kind = 'linear')
              def __call__(self, x):
                  ans = (self.y0(self.xfine))[numpy.searchsorted(self.xfine, x)]
                  return round(ans, 2)
          

          【讨论】:

          • 虽然这在其他情况下可能很常见,但在 numpy 代码中会非常不寻常。
          • 是什么让它在 numpy 代码中不寻常?这是方式,例如scipy.interpolate 使其所有返回函数的 1D 插值器工作,请参阅 herenumpy.poly1d 如何处理多项式求值函数,请参阅 here,或 numpy.vectorize 使向量化函数,请参阅 here
          猜你喜欢
          • 1970-01-01
          • 2015-08-30
          • 1970-01-01
          • 2017-11-14
          • 2018-05-02
          • 2021-11-24
          • 1970-01-01
          • 2023-03-11
          • 1970-01-01
          相关资源
          最近更新 更多