如果打印值,Numba JIT会更改结果

时间:2016-02-06 01:40:44

标签: python numpy jit numba

我今天开始使用numba,主要是因为我有一个嵌套的for循环,使用常规的python代码可能需要很长时间。

我有一个带有llvm-3.6的python-2.7的macports版本和numba的pip版本(一切都是最新的)

以下是我使用的代码:

import pandas as pd
from numba import jit
from numpy import nan, full

@jit
def movingAverage(adj_close, maxMA):
    ma = full([len(adj_close), maxMA], nan, dtype=float64)
    ind = range( 1, len(adj_close)+1 )
    for d in ind:
        m = max( 0, d-maxMA-1)
        adj = adj_close[d-1:m:-1] if (m or d==maxMA+1) else adj_close[d-1::-1]
        cs = adj.cumsum()
        for i in range( len(adj) ):
            ma[d-1][i] = ( cs[i] / (i+1) )
        print ma
    return ma

我计算输入adj_close的滚动均值最多maxMA天。

adj_close是一组值,每天一个值

我开始创建ma,这是将要计算的值的持有者。并单独计算每一天的vaules(请注意,第一天只能平均涉及1天,第二天,2,依此类推,直到maxMA)

如果我输入adj_close = array(range(5), dtype=float64)maxMA = 3之类的内容,请按以下方式获得正确答案:

array([[  0.,  nan,  nan],
       [  1.,   0.5,  nan],
       [  2.,   1.5,   1.],
       [  3.,   2.5,   2.],
       [  4.,   3.5,   3.]])

但是,如果我在返回函数之前取出print ma行,它只返回部分答案:

array([[ nan,  nan,  nan],
       [ nan,  nan,  nan],
       [ nan,  nan,  nan],
       [  3.,   2.5,   2.],
       [  4.,   3.5,   3.]])

为什么会这样?为什么@jit需要在这些循环之间打印以获得正确的答案?我该怎么做才能摆脱print语句(这会大大增加运行时间)?

编辑:我接受了@JoshAdel建议并在Numba的github上开了issue。因此,我接受了@MSeifert的答案,因为解决方法为我解决了这个问题。

1 个答案:

答案 0 :(得分:1)

我认为_loadfinished()在这里做了一些奇怪的事情,但可能是因为numbapython模式的混合。如果我使用Python 3.5,则返回值与nopython相同。

对于python 2.7我认为问题是因为for循环是以print模式(无打印)或nopython模式(带打印)编译的。但是当它退出循环时转换为python。但这只是猜测。但我尝试了:

python

它确实会返回:

import pandas as pd
from numba import jit
from numpy import nan, full
import numpy as np

@jit
def movingAverage(adj_close, maxMA):
    ma = full([len(adj_close), maxMA], nan, dtype=np.float64)
    ind = range( 1, len(adj_close)+1 )
    for d in ind:
        m = max( 0, d-maxMA-1)
        adj = adj_close[d-1:m:-1] if (m or d==maxMA+1) else adj_close[d-1::-1]
        cs = adj.cumsum()
        for i in range( len(adj) ):
            ma[d-1][i] = ( cs[i] / (i+1) )
        if d == ind[-1]:
            return ma # notice that I return it after the last loop but before the loop terminates.
    #return ma

然而,由于重新计算array([[ 0., nan, nan], [ 1., 0.5, nan], [ 2., 1.5, 1.], [ 3., 2.5, 2.], [ 4., 3.5, 3.]]) ,这不是一种非常有效的方式。这可以存储在某个地方。