Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 无效使用参数类型为的函数_Python_Numpy_Numba - Fatal编程技术网

Python 无效使用参数类型为的函数

Python 无效使用参数类型为的函数,python,numpy,numba,Python,Numpy,Numba,我使用的是Numba nonpython模式和一些NumPy函数 @njit def反转(W,复制=真): ''' 按元素反转输入连接矩阵中的权重。 换句话说,将节间强度矩阵更改为 节间距离矩阵。 如果未设置复制,此功能将*就地修改W* 参数 ---------- W:np.Ndaray 加权连通矩阵 抄送:布尔 退换商品 ------- W:np.Ndaray 逆连通矩阵 ''' 如果是副本: W=W.copy() E=np,其中(W) W[E]=1./W[E] 返回W 在此函数中,W是一个

我使用的是Numba nonpython模式和一些NumPy函数

@njit
def反转(W,复制=真):
'''
按元素反转输入连接矩阵中的权重。
换句话说,将节间强度矩阵更改为
节间距离矩阵。
如果未设置复制,此功能将*就地修改W*
参数
----------
W:np.Ndaray
加权连通矩阵
抄送:布尔
退换商品
-------
W:np.Ndaray
逆连通矩阵
'''
如果是副本:
W=W.copy()
E=np,其中(W)
W[E]=1./W[E]
返回W
在此函数中,
W
是一个矩阵。但是我犯了以下错误。它可能与
W[E]=1有关W[E]

File "/Users/xxx/anaconda3/lib/python3.7/site-packages/numba/dispatcher.py", line 317, in error_rewrite
    reraise(type(e), e, None)
  File "/Users/xxx/anaconda3/lib/python3.7/site-packages/numba/six.py", line 658, in reraise
    raise value.with_traceback(tb)
numba.errors.TypingError: Failed in nopython mode pipeline (step: nopython frontend)
Invalid use of Function(<built-in function getitem>) with argument(s) of type(s): (array(float64, 2d, A), tuple(array(int64, 1d, C) x 2))
文件“/Users/xxx/anaconda3/lib/python3.7/site packages/numba/dispatcher.py”,第317行,错误\u重写
重放(类型(e),e,无)
文件“/Users/xxx/anaconda3/lib/python3.7/site-packages/numba/six.py”,第658行,重新播放
通过_回溯(tb)提升值
numba.errors.TypingError:在nopython模式管道中失败(步骤:nopython前端)
函数()与类型为(数组(float64,2d,A)、元组(数组(int64,1d,C)x 2)的参数一起使用无效

那么,使用NumPy和Numba的正确方法是什么?我知道NumPy在矩阵计算方面做得很好。在这种情况下,NumPy的速度是否足够快,以至于Numba不再提供加速功能?

正如FBruzzesi在评论中提到的,代码没有编译的原因是您使用了“奇特的索引”,因为
W[E]
中的
E
np.where
的输出,是数组的元组。(这就解释了这个略显晦涩的错误消息:Numba不知道如何使用
getitem
,也就是说,当其中一个输入是元组时,它不知道如何在括号中查找某些内容。)

Numba,只是没有多个维度。在您的情况下,这允许进行一个简单的修改:首先使用
ravel
几乎无成本地将阵列变成一维,然后应用转换,然后再对其进行廉价的
重塑

@njit
def invert2(W, copy=True):
    if copy:
        W = W.copy()
    Z = W.ravel()
    E = np.where(Z)
    Z[E] = 1. / Z[E]
    return Z.reshape(W.shape)
但这仍然比需要的慢,因为它通过不必要的中间数组传递计算,而不是在遇到非零值时立即修改数组。简单地做一个循环会更快:

@njit 
def invert3(W, copy=True): 
    if copy: 
        W = W.copy() 
    Z = W.ravel() 
    for i in range(len(Z)): 
        if Z[i] != 0: 
            Z[i] = 1/Z[i] 
    return Z.reshape(W.shape) 
无论
W
的尺寸如何,此代码都有效。如果我们知道
W
是二维的,那么我们可以直接在这两个维度上迭代,但是因为这两个维度的性能相似,所以我选择更一般的路线

在我的计算机上,假设一个300×300的数组
W
,其中大约一半的条目是0,并且
invert
是您没有编译的原始函数,则计时为:

In [80]: %timeit invert(W)                                                                   
2.67 ms ± 49.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [81]: %timeit invert2(W)                                                                  
519 µs ± 24.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [82]: %timeit invert3(W)                                                                  
186 µs ± 11.1 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

因此,Numba给了我们相当大的加速(在它已经运行一次以消除编译时间之后),特别是在代码以Numba可以利用的高效循环方式重写之后。

正如FBruzzesi在评论中提到的,代码没有编译的原因是您使用了“奇特的索引”,因为
W[E]
中的
E
np.where
的输出,是数组的元组。(这就解释了这个略显晦涩的错误消息:Numba不知道如何使用
getitem
,也就是说,当其中一个输入是元组时,它不知道如何在括号中查找某些内容。)

Numba,只是没有多个维度。在您的情况下,这允许进行一个简单的修改:首先使用
ravel
几乎无成本地将阵列变成一维,然后应用转换,然后再对其进行廉价的
重塑

@njit
def invert2(W, copy=True):
    if copy:
        W = W.copy()
    Z = W.ravel()
    E = np.where(Z)
    Z[E] = 1. / Z[E]
    return Z.reshape(W.shape)
但这仍然比需要的慢,因为它通过不必要的中间数组传递计算,而不是在遇到非零值时立即修改数组。简单地做一个循环会更快:

@njit 
def invert3(W, copy=True): 
    if copy: 
        W = W.copy() 
    Z = W.ravel() 
    for i in range(len(Z)): 
        if Z[i] != 0: 
            Z[i] = 1/Z[i] 
    return Z.reshape(W.shape) 
无论
W
的尺寸如何,此代码都有效。如果我们知道
W
是二维的,那么我们可以直接在这两个维度上迭代,但是因为这两个维度的性能相似,所以我选择更一般的路线

在我的计算机上,假设一个300×300的数组
W
,其中大约一半的条目是0,并且
invert
是您没有编译的原始函数,则计时为:

In [80]: %timeit invert(W)                                                                   
2.67 ms ± 49.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [81]: %timeit invert2(W)                                                                  
519 µs ± 24.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [82]: %timeit invert3(W)                                                                  
186 µs ± 11.1 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
因此,Numba给了我们相当大的加速(在它已经运行一次以消除编译时间之后),特别是在代码以Numba可以利用的高效循环方式重写之后。

Numba不支持“花式”索引,请检查。如果两个数组都不支持“奇特”索引,请检查。您应该沿着两个数组维度循环