【问题标题】:Python Numpy Outer Product Apply List Of Functions To List Of Arguments Without For LoopsPython Numpy 外部产品将函数列表应用于没有 For 循环的参数列表
【发布时间】:2021-07-26 14:08:22
【问题描述】:

我有一个数字数组和一个函数列表。

我想对每个数字运行每个函数以返回一个矩阵。

有没有办法在没有慢速 python 循环/映射的情况下做到这一点?

import numpy
    arr = numpy.array([1,2,3,4,5])
    fns = [numpy.sin, numpy.cos, numpy.exp]
    results = numpy.zeros(shape=( len(fns), len(arr) ))
    for i, fn in enumerate(fns):
        for j, val in enumerate(arr):
            results[i][j] = fn(val)
    print ('results', results)

我可以通过函数广播摆脱一个循环:

results2 = numpy.zeros(shape=( len(fns), len(arr) ))
    for i, fn in enumerate(fns):
        results2[i] = fn(arr)
    print ('results2', results2)

有没有一些聪明的 pythonic numpy-ish 方法来摆脱我的第二个循环?

也许一些内置的外部产品交互很难用谷歌搜索?

results3 = numpy.function_outer( fns, arr)

【问题讨论】:

  • Numpy 不知道如何向量化fns。您可以创建一个 lambda 函数并使用 numpy 的 frompyfuncapply_along_axis,但这只会稍微减慢速度。
  • 我找到了与您的问题相关的链接stackoverflow.com/questions/44614254/…
  • 这不是一个正确的答案——但我意识到对于我的特定示例,sin、cos 和 exp 都属于同一个 exp(ix) 函数系列。一个聪明的实现是可以将指数函数应用于矩阵....但这对于更一般的情况是无用的。

标签: python numpy vectorization


【解决方案1】:

您可以使用列表推导式并将其转换回 numpy 数组,如下所示:

results3 = numpy.array([ fn(arr) for fn in fns])

【讨论】:

  • 这写起来更简洁,但速度并不快,因为它仍然是一个 for 循环。
  • 我不能同意,因为这是一种蟒蛇的方式,正如它所要求的那样。
  • “有没有办法在没有慢速python循环/映射的情况下做到这一点?”
  • @RandomGuy 这取决于你所说的慢是什么意思。根据我的测量,答案中的解决方案每个循环需要 5.84 µs ± 257 ns(平均值 ± 标准偏差,7 次运行,每个循环 100000 次)。与经典循环的解决方案相比,它的时间不到一半。
  • 作者期望像apply_along_axis这样的numpy函数可以做到这一点,但经过一些研究,这似乎是不可能的。此外,我尝试了您的解决方案,但我没有测量两次执行时间之间的任何显着差异,您能否提供一段代码以便我进行比较?
猜你喜欢
  • 1970-01-01
  • 2016-07-31
  • 2022-01-03
  • 1970-01-01
  • 2023-02-02
  • 2017-03-16
  • 2019-10-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多