我正在尝试编写一个可以由 numba 向量化的函数,以充当一组数组上的 ufunc:
from numba import float32, float64, vectorize
@vectorize([float32, float32, float32, float32(float32, float32, float32, float32, float32, float32, float32, numba.float32),
float64, float64, float64, float64(float64, float64, float64, float64, float64, float64, float64, numba.float64)])
def _cafec_coeff_ufunc(ET_bar,
PET_bar,
R_bar,
PR_bar,
L_bar,
PL_bar,
RO_bar,
PRO_bar):
# calculate alpha
if PET_bar == 0:
if ET_bar == 0:
alpha = 1
else:
alpha = 0
else:
alpha = ET_bar / PET_bar
# calculate beta
if PR_bar == 0:
if R_bar == 0:
beta = 1
else:
beta = 0
else:
beta = R_bar / PR_bar
# calculate gamma
if PRO_bar == 0:
if RO_bar == 0:
gamma = 1
else:
gamma = 0
else:
gamma = RO_bar / PRO_bar
# calculate delta
if PL_bar == 0:
if L_bar == 0:
delta = 1
else:
delta = 0
else:
delta = L_bar / PL_bar
return alpha, beta, gamma, delta
我在另一个函数中调用上述函数,将它需要的八个数组作为参数传递。我的期望是这个函数将以广播方式应用,就好像每个元素 i 的一维循环(假设所有输入数组大小相等),ufunc 从第 i 个索引处的每个数组获取标量作为其参数,最后在输出数组的第 i 个位置返回四个具有相应值的数组(ufunc 广播的结果减少为输出数组)。
alpha, beta, gamma, delta = _cafec_coeff_ufunc(ETbar, PETbar, Rbar, PRbar, Lbar, PLbar, RObar, PRObar)
当我将上面的代码作为调用方法的单元测试的一部分运行时,我在控制台中收到以下错误:
File "C:\home\git\indices_python\palmer.py", line 342, in <module>
numba.float64, numba.float64, numba.float64, numba.float64(numba.float64, numba.float64, numba.float64, numba.float64, numba.float64, numba.float64, numba.float64, numba.float64)])
File "C:\Anaconda3\lib\site-packages\numba\npyufunc\decorators.py", line 120, in wrap
vec.add(sig)
File "C:\Anaconda3\lib\site-packages\numba\npyufunc\dufunc.py", line 139, in add
args, return_type = sigutils.normalize_signature(sig)
File "C:\Anaconda3\lib\site-packages\numba\sigutils.py", line 35, in normalize_signature
% (sig.__class__.__name__,))
TypeError: invalid signature: 'Float' instance not allowed
我可以通过在签名本身周围添加引号来修改签名,以便将其转换为字符串。当我这样做时,错误现在变成了:
File "C:\home\git\indices_github\palmer.py", line 346, in <module>
@numba.vectorize(['f8,f8,f8,f8(f8,f8,f8,f8,f8,f8,f8,f8)'])
File "C:\home\Anaconda3\lib\site-packages\numba\npyufunc\decorators.py", line 120, in wrap
vec.add(sig)
File "C:\home\Anaconda3\lib\site-packages\numba\npyufunc\dufunc.py", line 139, in add
args, return_type = sigutils.normalize_signature(sig)
File "C:\home\Anaconda3\lib\site-packages\numba\sigutils.py", line 45, in normalize_signature
check_type(ty)
File "C:\home\Anaconda3\lib\site-packages\numba\sigutils.py", line 40, in check_type
"got %r" % (ty,))
TypeError: invalid signature: expected a type instance, got (float64, float64, float64, float64, float64, float64, float64, float64) -> float64
谁能建议我在这里做错了什么?在此先感谢您的任何建议。