使用Numba的@jit与Python中使用的Numpy的float32导致数学不一致

时间:2019-01-18 22:32:48

标签: python numpy numba

在将Numba的let productIsInStock = () => product => { ... } render(h) { return h('button', { '@click': () => this.addProductToCard(product), ':disabled': () => productIsInStock()(product), // using arrow fn instead of the getter } } 与Numpy的@jit数据类型一起使用时,我会截断吗?问题。很大程度上是噪音,因为它远远超过了我关心的小数点(大约在第7位或第8位),但是知道发生了什么以及是否可以解决它仍然很好。

顺便说一句,我不得不使用float32数据类型来节省内存!

这是我用来测试的代码:

float32

结合以下功能

import numpy as np
from test_numba import test_numba

np.random.seed(seed=1774);
number = 150;
inArray = np.round(np.float32((np.random.rand(number)-.5)*2),4); #set up a float32 with 4 decimal places
numbaGet = test_numba(inArray); #run it through
print("Get:\t"+str(numbaGet)+" Type: "+str(type(numbaGet)));
print("Want:\t"+str(np.mean(inArray))+" Type: "+str(type(np.mean(inArray)))); #compare to expected

输出是:

import numpy as np
from numba import jit #, float32

@jit(nopython=True) #nopython=True, nogil=True, parallel=True, cache=True , nogil=True, parallel=True #float32(float32),
def test_numba(inArray):

    #outArray = np.float32(np.mean(inArray)); #forcing float32 did not change it
    outArray = np.mean(inArray);

    return outArray;

这似乎表明Numba使其成为Python Get: 0.0982406809926033 Type: <class 'float'> Want: 0.09824067 Type: <class 'numpy.float32'> 类(据我所知float)并进行数学运算,然后以某种方式失去精度。

如果我切换到float64,差异将大大减小。

float64

不知道我在做什么错。同样,对于我来说,这是一个可忽略的问题(从小数点后4位开始),但仍然想知道为什么!

1 个答案:

答案 0 :(得分:4)

原因是,numba不使用np.mean,而是将其替换为/推出了its own version

def array_mean_impl(arr):
    # Can't use the naive `arr.sum() / arr.size`, as it would return
    # a wrong result on integer sum overflow.
    c = zero
    for v in np.nditer(arr):
        c += v.item()
    return c / arr.size

前段时间,我向an answer to a very similar question介绍了numpy.meanpandas.mean(使用bottleneck)之间的区别。所以说的所有内容在这里也适用,请简要查看一下以获取更多详细信息:

  • numba使用的天真求和具有错误O(n),其中n是求和数。
  • Numpy使用类似于pairwise-summation的方法,这种方法在出现错误O(log(n))时更为精确。
  • 对于float32,差异是显而易见的,但对于float64,差异并不明显,尽管仍然存在相同的问题。