numpy中frompyfunc和vectorize的区别

46

在numpy中,vectorizefrompyfunc有什么区别?

它们看起来非常相似。每个的典型用例是什么?

编辑:正如JoshAdel所指出的那样,类vectorize似乎是建立在frompyfunc之上的(参见the source)。我仍然不清楚frompyfunc是否有任何未被vectorize覆盖的用例...


有没有任何numpy开发者可以澄清一下这个问题?Numpy有许多这样的情况,在文档中高级和低级实现之间没有指针。 - dtlussier
由于某些秘密原因,frompyfunc 生成的函数有意忽略 dtype 参数并返回一个 object 数组。正如文档所解释的那样,“返回的 ufunc 总是返回 PyObject 数组”。有一个简单而巧妙的解决方法:将所需类型的数组作为 out 参数提交。相反,vectorize 函数允许使用 otypes 参数指定 ufunc 的输出类型,但它被认为速度较慢,因此与使用嵌套列表相比几乎没有用处。 - Alexey
如果有人想进一步探讨速度参数,可以参考这个问题/回答(https://dev59.com/nTgCtIcB2Jgan1zn0fF-#74596788),提供了1000倍的加速。 - Neil_UK
3个回答

28

正如JoshAdel指出的那样,vectorize封装了frompyfunc。Vectorize添加了以下额外功能:

  • 从原始函数复制文档字符串
  • 允许您从广播规则中排除一个参数。
  • 返回正确dtype的数组,而不是dtype=object

编辑:经过一些简短的基准测试,我发现vectorizefrompyfunc慢得多(约50%)适用于大型数组。如果性能在您的应用程序中至关重要,请首先对您的用例进行基准测试。

`

>>> a = numpy.indices((3,3)).sum(0)

>>> print a, a.dtype
[[0 1 2]
 [1 2 3]
 [2 3 4]] int32

>>> def f(x,y):
    """Returns 2 times x plus y"""
    return 2*x+y

>>> f_vectorize = numpy.vectorize(f)

>>> f_frompyfunc = numpy.frompyfunc(f, 2, 1)
>>> f_vectorize.__doc__
'Returns 2 times x plus y'

>>> f_frompyfunc.__doc__
'f (vectorized)(x1, x2[, out])\n\ndynamic ufunc based on a python function'

>>> f_vectorize(a,2)
array([[ 2,  4,  6],
       [ 4,  6,  8],
       [ 6,  8, 10]])

>>> f_frompyfunc(a,2)
array([[2, 4, 6],
       [4, 6, 8],
       [6, 8, 10]], dtype=object)

`


4
有趣...但差异和用例对我来说仍然不太清楚... - Olivier Verdier

10

我不确定它们各自的不同用例,但如果你查看源代码(/numpy/lib/function_base.py),你会发现vectorize包装了frompyfunc。我的理解是,vectorize在正确处理输入参数方面做得更好。也许在某些特定情况下,你会更喜欢其中之一,但似乎frompyfunc只是vectorize的一个较低级实例。


3
我同意你的观点,即frompyfunc似乎比vectorize更低级。然而,问题仍然存在,即是否存在你更愿意使用frompyfunc而不是vectorize的情况? - Olivier Verdier
1
我认为你不能像 https://dev59.com/cWYr5IYBdhLWcg3wQIC-#27912352 中那样在 vectorize 中使用 .accumulate - user3226167

6
尽管这两种方法都提供了一种构建自己的 ufunc 的方式,但使用 numpy.frompyfunc 方法始终返回一个 Python 对象,而使用 numpy.vectorize 方法时可以指定返回类型。

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