numpy.vectorize#
- class numpy.vectorize(pyfunc=np._NoValue, otypes=None, doc=None, excluded=None, cache=False, signature=None)[源代码]#
返回一个对象,该对象的行为类似于 pyfunc,但接受数组作为输入.
定义一个矢量化函数,该函数接受嵌套的对象序列或 numpy 数组作为输入,并返回一个单一的 numpy 数组或一个 numpy 数组的元组.矢量化函数在输入数组的连续元组上评估 pyfunc,类似于 python 的 map 函数,但它使用 numpy 的广播规则.
vectorized 的输出数据类型是通过使用输入的第一个元素调用该函数来确定的.这可以通过指定 otypes 参数来避免.
- 参数:
- pyfunc可调用,可选
一个Python函数或方法.可以省略以生成带有关键字参数的装饰器.
- otypesstr 或 dtypes 的列表,可选
输出数据类型.它必须指定为类型代码字符串或数据类型说明符列表.每个输出应有一个数据类型说明符.
- docstr, 可选
函数的文档字符串.如果为 None,文档字符串将是
pyfunc.__doc__
.- excludedset, 可选
一组字符串或整数,表示函数不会向量化的位置参数或关键字参数.这些参数将直接传递给 pyfunc 而不做修改.
在 1.7.0 版本加入.
- cachebool, 可选
如果 True,则在未提供 otypes 的情况下,缓存确定输出数量的第一个函数调用.
在 1.7.0 版本加入.
- signature字符串,可选
广义通用函数签名,例如,用于向量化矩阵向量乘法的
(m,n),(n)->(m)
.如果提供,``pyfunc`` 将以(并预期返回)形状由相应核心维度大小给出的数组.默认情况下,假定pyfunc
接受标量作为输入和输出.在 1.12.0 版本加入.
- 返回:
- outcallable
如果提供了
pyfunc
,则是一个矢量化函数;否则是一个装饰器.
参见
frompyfunc
接受任意 Python 函数并返回一个 ufunc
备注
vectorize
函数主要提供便利性,而不是性能.其实现本质上是一个 for 循环.如果未指定 otypes,则使用第一个参数调用该函数将用于确定输出的数量.如果 cache 为 True,则此调用的结果将被缓存以防止函数被调用两次.然而,为了实现缓存,必须包装原始函数,这会减慢后续调用的速度,因此只有在函数开销较大时才这样做.
新的关键字参数接口和 excluded 参数支持进一步降低了性能.
参考文献
[1]示例
>>> import numpy as np >>> def myfunc(a, b): ... "Return a-b if a>b, otherwise return a+b" ... if a > b: ... return a - b ... else: ... return a + b
>>> vfunc = np.vectorize(myfunc) >>> vfunc([1, 2, 3, 4], 2) array([3, 4, 1, 2])
除非指定,否则文档字符串取自输入函数
vectorize
:>>> vfunc.__doc__ 'Return a-b if a>b, otherwise return a+b' >>> vfunc = np.vectorize(myfunc, doc='Vectorized `myfunc`') >>> vfunc.__doc__ 'Vectorized `myfunc`'
输出类型是通过评估输入的第一个元素来确定的,除非另有指定:
>>> out = vfunc([1, 2, 3, 4], 2) >>> type(out[0]) <class 'numpy.int64'> >>> vfunc = np.vectorize(myfunc, otypes=[float]) >>> out = vfunc([1, 2, 3, 4], 2) >>> type(out[0]) <class 'numpy.float64'>
excluded 参数可以用来防止对某些参数进行向量化.这对于固定长度的类数组参数(如多项式的系数)非常有用,例如在
polyval
中:>>> def mypolyval(p, x): ... _p = list(p) ... res = _p.pop(0) ... while _p: ... res = res*x + _p.pop(0) ... return res >>> vpolyval = np.vectorize(mypolyval, excluded=['p']) >>> vpolyval(p=[1, 2, 3], x=[0, 1]) array([3, 6])
可以通过指定位置来排除位置参数:
>>> vpolyval.excluded.add(0) >>> vpolyval([1, 2, 3], x=[0, 1]) array([3, 6])
signature 参数允许对作用于固定长度非标量数组的函数进行矢量化.例如,你可以使用它来进行皮尔逊相关系数及其p值的矢量化计算:
>>> import scipy.stats >>> pearsonr = np.vectorize(scipy.stats.pearsonr, ... signature='(n),(n)->(),()') >>> pearsonr([[0, 1, 2, 3]], [[1, 2, 3, 4], [4, 3, 2, 1]]) (array([ 1., -1.]), array([ 0., 0.]))
或者对于矢量化卷积:
>>> convolve = np.vectorize(np.convolve, signature='(n),(m)->(k)') >>> convolve(np.eye(4), [1, 2, 1]) array([[1., 2., 1., 0., 0., 0.], [0., 1., 2., 1., 0., 0.], [0., 0., 1., 2., 1., 0.], [0., 0., 0., 1., 2., 1.]])
支持装饰器语法.装饰器可以作为函数调用以提供关键字参数:
>>> @np.vectorize ... def identity(x): ... return x ... >>> identity([0, 1, 2]) array([0, 1, 2]) >>> @np.vectorize(otypes=[float]) ... def as_float(x): ... return x ... >>> as_float([0, 1, 2]) array([0., 1., 2.])
方法
__call__
(*args, **kwargs)作为函数调用自身.