如何使numba(nopython = true)与元素数量未知的一维numpy.ndarray输入一起使用

我正在将(数学上复杂/涉及但很少的操作)自制的经验分布类从C ++ / MATLAB(我同时拥有)移植到Python。

文件有大约1100行代码,其中包括注释和测试数据,其中包括一个

if __name__ == "__main__": 

位于文件底部。

第83行具有函数声明:def cdf(self,x):

编译并运行良好的过程非常慢,所以我想使用@numba.jit(nopython=True)进行编译以使其运行更快。

但是,编译在文件npts=len(x)的函数的最早行之一(仅在它前面的注释)的第85行中终止。

该消息以:

结尾
[1] During: typing of argument at
C:\Users\kdalbey\Canopy\scripts\empDist.py (85)
--%<-----------------------------------------------------------------

File "Canopy\scripts\empDist.py",line 85

This error may have been caused by the following argument(s):
- argument 0: cannot determine Numba type of <class '__main__.empDist'>

现在我确实在文件顶部做了一个import numpy as np,但是为了使下面的消息更加清楚,我尝试将np替换为numpy。但是我可能错过了一些。

如果我使用npts=x.size,则会收到相同的错误消息。

所以我尝试将x输入为:

@numba.jit(nopython=True)
def cdf(self,x: numpy.ndarray(dtype=numpy.float64)):

我得到以下错误

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
C:\Users\kdalbey\Canopy\scripts\empDist.py in <module>()
     15 np.set_printoptions(precision=16)
     16 
---> 17 class empDist:
     18     def __init__(self,xdata):
     19         npts=len(xdata)
C:\Users\kdalbey\Canopy\scripts\empDist.py in empDist()
     81 
     82     @numba.jit(nopython=True)
---> 83     def cdf(self,x: np.ndarray(dtype=np.float64)):
     84         # compute the value of cdf at vector of points x
     85         npts = x.size
TypeError: Required argument 'shape' (pos 1) not found

但是我不知道1D numpy.ndarray预先有多少个元素(是任意的)

我猜我也许可以做

@numba.jit(nopython=True)
def cdf(self,x: numpy.ndarray(shape=(),dtype=numpy.float64)):

它克服了这个错误,只能返回到

[1] During: typing of argument at
C:\Users\kdalbey\Canopy\scripts\empDist.py (85)
--%<-----------------------------------------------------------------
File "Canopy\scripts\empDist.py",line 85
This error may have been caused by the following argument(s):
- argument 0: cannot determine Numba type of <class '__main__.empDist'>

如果我做npts=int(x.size)npts=numpy.int32(x.size)也是同样的错误,所以我发现问题出在x上。

zzz34486199 回答:如何使numba(nopython = true)与元素数量未知的一维numpy.ndarray输入一起使用

您的方法存在问题,因为存在多个问题(从numba版本0.46.0开始):

  • numpy.ndarray(shape=(),dtype=numpy.float64)实际上试图创建一个NumPy数组。您将其用作类型提示都没关系。它仍然执行(失败)。
  • 您应该在jit中使用更合适的(对于numba)签名,而不是类型提示。甚至更好:完全省略签名,让numba找出。在大多数情况下,numba会更好,并且花费更少的精力(如果您不需要限制类型)。
  • 您不能jit在nopython模式下使用方法。更好的方法是创建一个函数并从您的方法中调用它。

所以在您的情况下:

import numba as nb

@nb.njit
def _cdf(x):
    # do something with x

class empDist:
    def cdf(self,x):
        result = _cds(x)
        ...

您的示例可能更复杂,但是应该为您提供一个良好的起点。如果需要使用实例属性,则只需将它们传递给_cdf(如果numba支持them)。


通常,尝试在所有内容上使用numba并不是一个好主意。 Numba的范围非常有限,但在适用范围内可能会令人惊讶。

就您而言,这很慢。然后,第一步应该是分析您的代码,并找出为什么它很慢以及在哪里。然后尝试找出是否可以用更快的方法来解决此瓶颈。通常问题不在于代码本身,而在于算法/方法。检查它是否使用了次优方法。如果不是,那是一个很大的数字部分,那么使用numba可能会有意义-但要警告:通常您根本不需要numba,因为仅通过优化即可获得足够的性能NumPy部分。

,

好吧...问题是这是一个方法(成员函数),我是从MrFuppes那里得到的。将其隔离在自己的函数中,该方法调用的效果很好(几乎没有对使用pre-numba的函数进行mod修改)。

顺便说一句,我将尝试获得批准以发布/发布经验性分发代码,但这将是一条路。我也可能想学习cython并对其进行重新编码以提高cython的速度,由于运算在数学上是复杂的/涉及的,因此编译在我的机器上花费了O(秒),但是从触发器计数的角度来看并没有很多。与sklearn.neighbors.kde相比,我的经验分布卖点要快得多(在@ numba.jit(nopython = True)编译缓存之后/折价)。在Windows上运行顶篷(numba为0.36.2,因此np.interp不能从numba中受益),与 fitting sklearn kde(花费2.03e)相比,建立这种经验分布的时间为5.72e-5秒-4秒获得463点。此外,它应该很好地扩展到非常多的点。除了快速排序为O(n log(n))和插值为O(n)之外,构造(和存储对象所需的内存)成本为O(n ^(1/3))(系数显着到O(n ^(1/3))。它具有PDF,CDF和CDF逆分析的“简单”解析公式,因此经验分布也可以更快地很多进行评估。 /对于高斯来说,sklearn KDE的精度略好(使用带宽=(maxx-minx)* 0.015),我复制了带宽,因此使用sklearn kde的其他代码可能比我更好,显然,kde的精度很大程度上取决于在带宽上,我的经验分布在构造过程中除了数据外没有任何其他参数,它通过算法计算出了它需要了解的有关数据的所有信息),并且对于具有有限尾部(例如均匀或指数)的对象的准确性大大提高。准确性的部分原因是,它比sklearn kde更平滑/不那么摇摆。>

本文链接:https://www.f2er.com/3099938.html

大家都在问