Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.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 如何使用Numba对接受标量并返回向量的函数进行向量化?_Python_Performance_Parallel Processing_Vectorization_Numba - Fatal编程技术网

Python 如何使用Numba对接受标量并返回向量的函数进行向量化?

Python 如何使用Numba对接受标量并返回向量的函数进行向量化?,python,performance,parallel-processing,vectorization,numba,Python,Performance,Parallel Processing,Vectorization,Numba,我有一个函数,它接受两个标量并返回一个一维数组。例如: import numpy as np def linear_pattern(slope,length): pattern = slope*np.arange(length) return pattern 我的目标是能够一次对相同的标量值长度进行多个坡度,也就是说,我想运行 >>> linear_pattern(np.array([3,4]),10) array([[ 0., 3., 6., 9.,

我有一个函数,它接受两个标量并返回一个一维数组。例如:

import numpy as np
def linear_pattern(slope,length):
    pattern = slope*np.arange(length)
    return pattern
我的目标是能够一次对相同的标量值
长度
进行多个
坡度
,也就是说,我想运行

>>> linear_pattern(np.array([3,4]),10)
array([[ 0.,  3.,  6.,  9., 12., 15., 18., 21., 24., 27.],
       [ 0.,  4.,  8., 12., 16., 20., 24., 28., 32., 36.]])
而不是

>>> linear_pattern(3,10)
array([ 0,  3,  6,  9, 12, 15, 18, 21, 24, 27])
>>> linear_pattern(4,10)
array([ 0,  4,  8, 12, 16, 20, 24, 28, 32, 36])
我正在使用来自Numba的装饰师来做这项工作。以下是我的实施:

from numba import float64, guvectorize
@guvectorize( [(float64, float64, float64[:])], '(),() -> (n)' )
def linear_pattern(slope,length,pattern):
    pattern[:] = slope*np.arange(length)
但是,我在尝试运行以下示例时出错:

>>> pattern = np.zeros(10) 
>>> linear_pattern(np.array([3,4]),10,pattern)
NameError: undefined output symbols: n
由于我将函数的输出设置为维度
n
的向量,并且没有定义该维度,即我没有在输入维度的任何地方使用
n
,因此错误会出现。但是,输入都是标量,这就排除了使用
n

我的问题是:

  • 我如何才能使上述代码工作
  • 由于
    length
    始终是相同的标量,我更希望它是
    linear_pattern
    的kwarg,而不是arg,然而,decorator
    guvectorize
    似乎不接受带有kwarg类型参数的函数。
    guvectorize
    可以接受kwarg参数吗

  • 暂时,我通过定义一个与输出维度相同的伪变量
    \uu
    使代码正常工作。见下文:

    length = 10
    __ = np.zeros(length)
    
    @guvectorize( [(float64, float64, float64[:], float64[:])], '(),(),(n) -> (n)' )
    def linear_pattern(slope,length,__,pattern):
        pattern[:] = slope*np.arange(length)
    
    >>> pattern = np.zeros(length) 
    >>> linear_pattern(np.array([3,4]),length,pattern)
    array([[ 0.,  3.,  6.,  9., 12., 15., 18., 21., 24., 27.],
           [ 0.,  4.,  8., 12., 16., 20., 24., 28., 32., 36.]])
    

    编辑1:

    在我最初的问题中,我使用了需要矢量化的实际函数的简化版本。原来的一个有更多的参数,也需要响应矢量化

    以下面修改过的函数为例

    def linear_pattern(slope, intercept, length):
    pattern = slope*np.arange(length) + intercept
    return pattern
    
    然后我想跑步

    slopes = np.array([3, 4])
    intercepts = np.array([0, 1, 2])
    length = 10
    linear_pattern(slopes, intercepts, length)
    

    结果具有尺寸
    (len(斜率)、len(截距)、长度)
    ,在这种情况下,它是
    (2,3,10)
    。请注意,
    length
    始终是一个固定整数,并且不需要对该参数进行矢量化,事实上,理想的解决方案是将
    length
    保留为kwarg类型参数。

    如果您不介意
    线性模式
    返回矩阵,您可以使用NumPy的广播(无需Numba):

    输出:

    [[03 6 9 12 15 18 21 24 27]]
    [[ 0  3  6  9 12 15 18 21 24 27]
    [ 0  4  8 12 16 20 24 28 32 36]]
    
    这是怎么回事
  • np.arange(10).重塑((1,-1))
    is
    array([[0,1,2,3,4,5,6,7,8,9]])
  • 数组([[3],[4]])
  • 的元素级(!)乘法如下:
    如果您不介意
    linear\u pattern
    返回矩阵,您可以使用NumPy的广播(不需要Numba):

    输出:

    [[03 6 9 12 15 18 21 24 27]]
    [[ 0  3  6  9 12 15 18 21 24 27]
    [ 0  4  8 12 16 20 24 28 32 36]]
    
    这是怎么回事
  • np.arange(10).重塑((1,-1))
    is
    array([[0,1,2,3,4,5,6,7,8,9]])
  • 数组([[3],[4]])
  • 的元素级(!)乘法如下:
    如果你真的需要使用Numba,临时解决方案会存在很长时间。事实上,使用虚拟输入是可行的,因为根据,输出数组实际上是由NumPy的分派机制分配的,该机制调用Numba生成的代码

    现在您需要分配一个虚拟输入,
    length
    参数是多余的。相反,您可以分配完整的输出:

    @nb.guvectorize([(nb.float64, nb.float64[:], nb.float64[:])], '(),(n) -> (n)')
    def linear_pattern2(slope, __, pattern):
        pattern[:] = slope * np.arange(len(pattern))
    
    >>> pattern = np.empty((2, length))
    >>> linear_pattern2(np.array([3, 4]), pattern2)
    array([[ 0.,  3.,  6.,  9., 12., 15., 18., 21., 24., 27.],
           [ 0.,  4.,  8., 12., 16., 20., 24., 28., 32., 36.]])
    
    您可以使用
    out
    kwarg(由Numpy的ufunc规范自动提供)防止不必要的输出阵列分配,这可能与大型阵列相关:

    >>> pattern = np.empty((2, length))
    >>> linear_pattern2(np.array([3, 4]), pattern, out=pattern)
    >>> pattern
    array([[ 0.,  3.,  6.,  9., 12., 15., 18., 21., 24., 27.],
           [ 0.,  4.,  8., 12., 16., 20., 24., 28., 32., 36.]])
    
    函数的返回和输入数组是同一个对象:

    >>> pattern = np.empty((2, length))
    >>> lp = linear_pattern2(np.array([3, 4]), pattern, out=pattern)
    >>> lp is pattern
    True
    

    如果你真的需要使用Numba,临时解决方案会存在很长时间。事实上,使用虚拟输入是可行的,因为根据,输出数组实际上是由NumPy的分派机制分配的,该机制调用Numba生成的代码

    现在您需要分配一个虚拟输入,
    length
    参数是多余的。相反,您可以分配完整的输出:

    @nb.guvectorize([(nb.float64, nb.float64[:], nb.float64[:])], '(),(n) -> (n)')
    def linear_pattern2(slope, __, pattern):
        pattern[:] = slope * np.arange(len(pattern))
    
    >>> pattern = np.empty((2, length))
    >>> linear_pattern2(np.array([3, 4]), pattern2)
    array([[ 0.,  3.,  6.,  9., 12., 15., 18., 21., 24., 27.],
           [ 0.,  4.,  8., 12., 16., 20., 24., 28., 32., 36.]])
    
    您可以使用
    out
    kwarg(由Numpy的ufunc规范自动提供)防止不必要的输出阵列分配,这可能与大型阵列相关:

    >>> pattern = np.empty((2, length))
    >>> linear_pattern2(np.array([3, 4]), pattern, out=pattern)
    >>> pattern
    array([[ 0.,  3.,  6.,  9., 12., 15., 18., 21., 24., 27.],
           [ 0.,  4.,  8., 12., 16., 20., 24., 28., 32., 36.]])
    
    函数的返回和输入数组是同一个对象:

    >>> pattern = np.empty((2, length))
    >>> lp = linear_pattern2(np.array([3, 4]), pattern, out=pattern)
    >>> lp is pattern
    True
    

    我不介意
    线性模式
    返回矩阵。但是,我需要将向量化应用于一个函数,该函数具有多个需要接受向量化的参数。请参见我问题中的编辑1。我试图在编辑1中以修改后的
    linear\u pattern
    形式使用“.reformate((1,-1))”,但是没有得到预期的结果。我认为使用Numba可以将矢量化扩展到所需的任意多个参数。我不介意
    线性模式
    返回矩阵。但是,我需要将向量化应用于一个函数,该函数具有多个需要接受向量化的参数。请参见我问题中的编辑1。我试图在编辑1中以修改后的
    linear\u pattern
    形式使用“.reformate((1,-1))”,但是没有得到预期的结果。我认为使用Numba可以根据需要将矢量化扩展到尽可能多的参数。