【问题标题】:Numpy - writing a function in vector form?Numpy - 以向量形式编写函数?
【发布时间】:2021-01-10 14:52:48
【问题描述】:

我对 NumPy(或 SciPy)很陌生,并且来自 Octave/Matlab,这对我来说似乎有点挑战。

我正在阅读文档并编写一些基本功能。我遇到了这个部分:Vectorizing functions (vectorize)

它定义了这个函数:

def addsubtract(a, b):
   if a > b:
       return a - b
   else:
       return a + b

然后向量化它:

vec_addsubtract = np.vectorize(addsubtract)

但最后,它说:

这个特殊的函数可以不用vectorize就可以写成向量形式。

我不知道有任何其他方法可以编写这样的函数。那么什么是向量形式呢?

【问题讨论】:

  • this 对您有帮助吗?
  • 检查NumPy for MATLAB users。如果您有 NumPy 数组,则可以像使用 MATLAB 中的数组(矩阵)一样使用它们。大多数 NumPy 操作已经在整个数组上工作,因此不需要(额外)对任何东西进行矢量化。
  • 在这样的介绍中引入np.vectorize 可能不是一个好主意。我看到太多来自初学者的 SO 问题因为试图使用它而误入歧途。实际上 numpy's 整个数组的功能与 Octave 的非常相似。

标签: python numpy vectorization


【解决方案1】:

np.vectorize 是一个美化的 python for 循环,这意味着它有效地去除了 numpy 提供的任何优化。

要真正矢量化 addsubtract,我们可以利用 numpy 提供三样东西的事实:矢量化 add 函数、矢量化 subtract 函数以及各种布尔掩码操作。

最简单但效率最低的编写方法是使用np.where

np.where(a > b, a - b, a + b)

这是低效的,因为它在所有情况下预先计算a - ba + b,然后为每个元素从一个或另一个中进行选择。

更有效的解决方案只计算条件需要的值:

result = np.empty_like(a)
mask = a > b
np.subtract(a, b, where=mask, out=result)
np.add(a, b, where=~mask, out=result)

对于非常小的数组,复杂方法的开销使其不值得。但对于大型数组,这是最快的解决方案。

有趣的事实:您所引用的教程中的页面在 SciPy 教程的未来版本中将不可用,因为它是 NumPy 的介绍,如 PR #12432 中所述。 p>

【讨论】:

    【解决方案2】:

    您可以使用 np.where 执行此操作,它会计算两个结果(a-ba+b)并根据布尔数组(a>b)选择值:

    def addsubtract(a, b):
        return np.where(a>b, a-b, a+b)
    

    可以看成一个向量化的三元运算符:“where a>b,取a-b的值,else取a+b的值”。

    尽管计算了两种可能的结果,但它比您编写的向量化 if/else 函数快得多(至少在我的机器上)。

    【讨论】:

      猜你喜欢
      • 2015-12-08
      • 1970-01-01
      • 1970-01-01
      • 2021-04-14
      • 1970-01-01
      • 1970-01-01
      • 2017-10-25
      • 2017-05-25
      • 1970-01-01
      相关资源
      最近更新 更多