NumPy -如何以向量形式编写函数?

3

我对NumPy(或SciPy)相当陌生,来自Octave/Matlab,这对我来说似乎有些具有挑战性。

我正在阅读文档并编写一些基本函数。我遇到了这个部分:向量化函数(vectorize)

它定义了这个函数:

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

然后将其向量化:

vec_addsubtract = np.vectorize(addsubtract)

但是最后一句话说:

这个特定函数本可以用向量形式编写而不需要使用 vectorize。

我不知道其他编写此类函数的方法。那么什么是向量形式呢?


1
这个链接对你有帮助吗? - Niklas Mertsch
1
请查看NumPy for MATLAB users。如果您有NumPy数组,您可以像在MATLAB中使用数组(矩阵)一样使用它们。大多数NumPy操作已经可以在整个数组上工作,因此没有必要(另外)对任何内容进行向量化处理。 - HansHirse
在介绍中引入np.vectorize可能不是一个好主意。我看到太多初学者因尝试使用它而被误导的问题。实际上,numpy的整个数组功能与Octave非常相似。 - hpaulj
2个回答

1
你可以使用np.where来实现这一点,它会计算两个结果(a-ba+b)并根据布尔数组(a>b)选择值:
def addsubtract(a, b):
    return np.where(a>b, a-b, a+b)

这可以被看作是一个向量化的三元操作符:“当a>b时,从a-b中获取值,否则从a+b中获取值”。

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


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中所解释的那样。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接