如何使用numpy.vectorize()

时间:2019-02-04 20:22:57

标签: python numpy vectorization numpy-broadcasting

我正在编写一个自定义函数,就好像它在一个numpy函数中一样,具有接受数组的能力,并且可以对输入列表的每个元素执行相同的操作,并返回一个列表所有结果的形状相同。

幸运的是,有一个解决方案:numpy.vectorize()

所以我用了:我有一个函数以正弦波的形式创建一个模型,它包含两个变量:一个numpy列表X包含一些正弦函数的输入值,另一个numpy list param,其中包含正弦曲线可以具有的四个可能的参数。

import numpy as np
def sine(X, param):
    #Unpacking param
    A = param[0]
    P = param[1]
    Phi = param[2]
    B = param[3]

    #translating variables
    #Phi = t0/P
    f = X/P
    Y = A*np.sin(2*np.pi*(f + Phi)) + B
    return Y

因为只有输入值X才需要广播,而所有参数始终都是必需的,所以根据文档,对功能进行跟踪的方法如下:

np_sine = np.vectorize(sine, excluded=['param']) #makes sine() behave like a numpy function

...以便将param正确地排除在矢量化之外。

该方法很有用,因为我会将模型拟合到数据集,这有时需要调整参数,与此同时,使用此方法,我需要的代码只有一行:

CHIsqrt = np.sum(((ydata - np_sine(xdata, param))/yerr)**2)

其中ydataxdatayerr是同样长的数据点列表,而param是四个参数的列表。

但是,结果是广播错误:

 File "C:\Users\Anonymous\AppData\Local\Programs\Python\Python36\lib\site-packages\numpy\lib\function_base.py", line 2831, in _vectorize_call outputs = ufunc(*inputs)
 ValueError: operands could not be broadcast together with shapes (500,) (4,)

由于列表param的长度为4个元素,因此我认为该函数忽略了我的命令,以将其从向量化中排除。那是个问题。

我尝试指定最终结果应为ndArray,但不会更改错误。

np_sine = np.vectorize(sine, excluded=['param'], otypes=[np.ndarray])

使用此功能的正确方法是什么?

1 个答案:

答案 0 :(得分:1)

您指定的excluded错误。

In [270]: def foo(x, param):
     ...:     a,b,c = param
     ...:     return a*x
     ...: 
In [271]: f = np.vectorize(foo, excluded=[1])  # specify by position
In [272]: f(np.arange(4),[1,3,2])
Out[272]: array([0, 1, 2, 3])

对于关键字arg:

In [277]: def foo(x, param=[0,0,0]):
     ...:     a,b,c = param
     ...:     return a*x
     ...:
In [278]: f = np.vectorize(foo, excluded=['param'])
In [279]: f(np.arange(4),param=[1,3,2])
Out[279]: array([0, 1, 2, 3])