【问题标题】:numba :cannot determine Numba type of <class 'function'> pythonnumba:无法确定 <class 'function'> python 的 Numba 类型
【发布时间】:2021-06-09 19:51:54
【问题描述】:

这是我的代码。

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 类型。 请问有人知道怎么解决吗? 非常感谢。

【问题讨论】:

  • 请只发布代码中绝对相关的部分
  • 很抱歉,您认为哪一部分不相关?

标签: python numba


【解决方案1】:

有几个问题需要处理:首先,您已经注释掉了第一个函数 stopF_w@jit 装饰器。

如果您取消注释,您将解决当前的错误。不幸的是,您将立即遇到其他几个错误。如果您的 numba 版本是最新的,您将看到与“反射列表”有关的错误。

基本上,您的输入 b_wif_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),那么它将毫无问题地工作。让您的可变长度列表与 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_nbf_wi_nb 作为输入。

另一个问题:函数stopF_w 有两个“if”块。如果两个条件都不满足,is 可能会返回 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')

【讨论】:

  • 非常感谢您的长篇回答。问题是,输入 b_wi 和 f_wi 的长度是不同的。这就是为什么这个问题对我来说如此棘手。我考虑过使用多处理包。但我无法在此链接中找出问题stackoverflow.com/questions/67909376/…
  • 我尝试了您的解决方案。它现在有效!非常感谢!!!
  • 我还有一个问题。因为我需要使用 List() 传输列表。那么计算时间会因为转换而增加。请问您知道如何处理吗?当我在实际问题中尝试您的解决方案时,由于我的列表长度太大,时间增加了很多。
  • 不确定它是否会工作,但您可以尝试安装以前版本的 numba,这与正常的列表列表没有问题。根据numba.pydata.org/numba-doc/latest/reference/deprecation.html 的说法,似乎
  • 但是我无法在 averageF_w 中创建池,因为我需要 'if name == "main": '
猜你喜欢
  • 2021-03-04
  • 2018-11-17
  • 2021-07-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-23
  • 1970-01-01
相关资源
最近更新 更多