numba :无法确定 <class 'function'> python 的 Numba 类型
numba :cannot determine Numba type of <class 'function'> python
这是我的代码。
from numba import jit
import numpy as np
import time
from pandas.core.common import flatten
from numba import njit
b_wi=[[1,2,3,4],[6,7,8,9,10,11]] #b_wi is a subset of x
f_wi=[[5,4,2,7,9],[5,4,3,7,2,3,4]]
# @jit(nopython=True)
def stopF_w(x,b_wi,f,di):
if di=='left':
return f[np.searchsorted(-b_wi,-x,side='left')]
if di=='right':
return f[np.searchsorted( b_wi, x,side='right')]
# this f :need to be an element in f_nslst
#b_wi :need to be an element in b_wilst
@njit(parallel=True)
def averageF_w(x,b_wilst,f_nslst,di):
a=np.zeros(x.shape[0])
for b_wi,f in zip(b_wilst,f_nslst):
a[:] += stopF_w(x,np.asarray(b_wi),np.asarray(f),di)
return a
intval= np.unique(list(flatten(b_wi)))
x=np.concatenate(([-10000],(intval[:-1]+intval[1:])/2,[10000])) #b_wi is a subset of x. That is why I can use this.
averageF_w(x,b_wi,f_wi,'right')
它引发错误:TypingError:无法确定 的 Numba 类型。
请问有人知道怎么修吗?
非常感谢。
有几个问题需要处理:首先,您已经注释掉了第一个函数 stopF_w
.
的 @jit
装饰器
如果取消注释,您将解决当前的错误。不幸的是,您会立即 运行 陷入其他几个错误。如果您的 numba 版本是最新的,您将看到与“反射列表”有关的错误。
基本上,您输入的b_wi
和f_wi
是可变长度列表的列表,无法转换为统一的numpy数组。例如:如果不是 [[1,2,3,4],[6,7,8,9,10,11]]
,如果 b_wi
类似于 [[1,2,3, 4, 6], [7, 8, 9, 10, 11]]
(可以轻松转换为形状 (2, 5) 的数组,那么它将毫无问题地工作。要获取您的变量length lists 与 numba 一起工作,你需要依赖一个 Typed List,这有点麻烦。
from numba import jit
import numpy as np
import time
from pandas.core.common import flatten
from numba import njit
from numba.typed import List
b_wi=[[1,2,3,4], [6,7,8,9,10,11]]
f_wi=[[5,4,2,7,9], [5,4,3,7,2,3,4]]
###########################
# Create typed Lists
###########################
b_wi_nb = List()
for i in range(len(b_wi)):
b = List()
for j in range(len(b_wi[i])):
b.append(b_wi[i][j])
b_wi_nb.append(b)
f_wi_nb = List()
for i in range(len(f_wi)):
f = List()
for j in range(len(f_wi[i])):
f.append(f_wi[i][j])
f_wi_nb.append(f)
我们稍后将使用 b_wi_nb
和 f_wi_nb
作为输入。
另一个问题:函数stopF_w
有两个“if”块。如果两个条件都不满足,可能 return None,这对于您的用例来说是 numba 不能接受的。因此,除了取消注释 jit 装饰器之外,您还需要将条件更改为 if-else 或 if-elif-else(视情况而定)。
@jit(nopython=True)
def stopF_w(x,b_wi,f,di):
if di=='left':
return f[np.searchsorted(-b_wi,-x,side='left')]
else:
return f[np.searchsorted( b_wi, x,side='right')]
经过上述更改后,numba 应该可以工作了。
@jit(nopython=True, parallel=True)
def averageF_w(x, b_wilst, f_nslst, di):
a = np.zeros(x.shape[0])
for b_wi, f in zip(b_wilst,f_nslst):
a += stopF_w(x, np.asarray(b_wi), np.asarray(f), di)
return a
intval= np.unique(list(flatten(b_wi)))
x=np.concatenate(([-10000],(intval[:-1]+intval[1:])/2,[10000]))
##############################
# initial compiles
##############################
stopF_w(np.arange(1),np.arange(1),np.arange(1),'right')
averageF_w(np.arange(10),np.arange(6).reshape(2, 3),np.arange(6).reshape(2, 3),'right')
##############################
averageF_w(x, b_wi_nb, f_wi_nb,'right')
这是我的代码。
from numba import jit
import numpy as np
import time
from pandas.core.common import flatten
from numba import njit
b_wi=[[1,2,3,4],[6,7,8,9,10,11]] #b_wi is a subset of x
f_wi=[[5,4,2,7,9],[5,4,3,7,2,3,4]]
# @jit(nopython=True)
def stopF_w(x,b_wi,f,di):
if di=='left':
return f[np.searchsorted(-b_wi,-x,side='left')]
if di=='right':
return f[np.searchsorted( b_wi, x,side='right')]
# this f :need to be an element in f_nslst
#b_wi :need to be an element in b_wilst
@njit(parallel=True)
def averageF_w(x,b_wilst,f_nslst,di):
a=np.zeros(x.shape[0])
for b_wi,f in zip(b_wilst,f_nslst):
a[:] += stopF_w(x,np.asarray(b_wi),np.asarray(f),di)
return a
intval= np.unique(list(flatten(b_wi)))
x=np.concatenate(([-10000],(intval[:-1]+intval[1:])/2,[10000])) #b_wi is a subset of x. That is why I can use this.
averageF_w(x,b_wi,f_wi,'right')
它引发错误:TypingError:无法确定
有几个问题需要处理:首先,您已经注释掉了第一个函数 stopF_w
.
@jit
装饰器
如果取消注释,您将解决当前的错误。不幸的是,您会立即 运行 陷入其他几个错误。如果您的 numba 版本是最新的,您将看到与“反射列表”有关的错误。
基本上,您输入的b_wi
和f_wi
是可变长度列表的列表,无法转换为统一的numpy数组。例如:如果不是 [[1,2,3,4],[6,7,8,9,10,11]]
,如果 b_wi
类似于 [[1,2,3, 4, 6], [7, 8, 9, 10, 11]]
(可以轻松转换为形状 (2, 5) 的数组,那么它将毫无问题地工作。要获取您的变量length lists 与 numba 一起工作,你需要依赖一个 Typed List,这有点麻烦。
from numba import jit
import numpy as np
import time
from pandas.core.common import flatten
from numba import njit
from numba.typed import List
b_wi=[[1,2,3,4], [6,7,8,9,10,11]]
f_wi=[[5,4,2,7,9], [5,4,3,7,2,3,4]]
###########################
# Create typed Lists
###########################
b_wi_nb = List()
for i in range(len(b_wi)):
b = List()
for j in range(len(b_wi[i])):
b.append(b_wi[i][j])
b_wi_nb.append(b)
f_wi_nb = List()
for i in range(len(f_wi)):
f = List()
for j in range(len(f_wi[i])):
f.append(f_wi[i][j])
f_wi_nb.append(f)
我们稍后将使用 b_wi_nb
和 f_wi_nb
作为输入。
另一个问题:函数stopF_w
有两个“if”块。如果两个条件都不满足,可能 return None,这对于您的用例来说是 numba 不能接受的。因此,除了取消注释 jit 装饰器之外,您还需要将条件更改为 if-else 或 if-elif-else(视情况而定)。
@jit(nopython=True)
def stopF_w(x,b_wi,f,di):
if di=='left':
return f[np.searchsorted(-b_wi,-x,side='left')]
else:
return f[np.searchsorted( b_wi, x,side='right')]
经过上述更改后,numba 应该可以工作了。
@jit(nopython=True, parallel=True)
def averageF_w(x, b_wilst, f_nslst, di):
a = np.zeros(x.shape[0])
for b_wi, f in zip(b_wilst,f_nslst):
a += stopF_w(x, np.asarray(b_wi), np.asarray(f), di)
return a
intval= np.unique(list(flatten(b_wi)))
x=np.concatenate(([-10000],(intval[:-1]+intval[1:])/2,[10000]))
##############################
# initial compiles
##############################
stopF_w(np.arange(1),np.arange(1),np.arange(1),'right')
averageF_w(np.arange(10),np.arange(6).reshape(2, 3),np.arange(6).reshape(2, 3),'right')
##############################
averageF_w(x, b_wi_nb, f_wi_nb,'right')