【问题标题】:How to efficiently evaluate a whole Python list of functions element-wise?如何有效地逐元素评估整个 Python 函数列表?
【发布时间】:2019-03-15 09:28:20
【问题描述】:

假设我有一个包含三个函数的列表:

f_list = [f1,f2,f3]

和一个值数组,每个函数都应该被计算

values = numpy.array([1,2,3])

这样我得到 f1(1)、f2(2) 和 f3(3)。

一种方法当然是循环函数:

for i in range(3):
    print(f_list[i](values[i])

有没有更有效的方法来做到这一点?类似于 numpy 数组操作的东西,我可以一次传递所有值以获取函数评估数组? 据我所知,我不能将函数存储在 numpy 数组中,可以吗?

在我的例子中,我有一个非常大的 scipy 插值 (interp1d) 函数(或调用对象)的 2D 列表,当在两个轴上循环时需要很长时间来评估。

【问题讨论】:

  • 我认为你想使用map,尽管它对 numpy 不是很有效。还有vectorize装饰器:docs.scipy.org/doc/numpy-1.13.0/reference/generated/…
  • 你确定你的程序需要很长时间是因为未优化的循环而不是不可避免的函数调用本身吗?
  • "据我所知,我不能将函数存储在 numpy 数组中,可以吗?"您可以将任何内容存储在 numpy 数组中;但如果它不是 numpy 原生的,它会得到dtype=object,如果 numpy 对速度有任何好处,你就会变得稀缺(尽管你仍然可以使用高级操作功能)。我可能只是做y = [f(x) for f, x in zip(f_list, values)] 或类似的 - 与您的代码一样的速度,但对我来说更具可读性
  • 你用的是什么版本的 Python?
  • Python 的内置 zip() [ 或者 izip() ] 函数。不过你仍然需要一个循环。

标签: python arrays performance function numpy


【解决方案1】:

对于任意 Python 函数,Python 级别的循环是不可避免的。一种方法是通过列表理解:

f_list = [f1,f2,f3]
values = np.array([1,2,3])
res = np.array([func(val) for func, val in zip(f_list, values)])

请记住,NumPy 不是用于将普通函数转换为向量化函数的高阶函数工具。甚至np.vectorize 也只不过是一个 Python 级别的循环。要矢量化您的计算,您需要依次考虑每个函数并编写一些逻辑,如果确实可以矢量化的话。

【讨论】:

    【解决方案2】:

    如果它们按顺序排列,则此代码将起作用:

    def a ( parameter ):
      print ( parameter )
    def b ( parameter ):
      print ( parameter )
    def c ( parameter ):
      print ( parameter )
    
    
    f_list = [a, b, c]
    v_list = [1, 2, 3]
    
    for index, function in enumerate ( f_list ):
        function ( v_list [ index ] )
    

    【讨论】:

    • 这与 OP 给出的解决方案有何不同?它绝对不能完成他/她的要求
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-25
    • 2020-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多