Python 如果打印了值,则会更改JIT结果
我今天开始使用numba,主要是因为我有一个嵌套的for循环,使用常规python代码可能需要很长时间 我有一个macports版本的python-2.7和llvm-3.6,还有一个pip版本的numba(一切都是最新的) 以下是我正在使用的代码:Python 如果打印了值,则会更改JIT结果,python,numpy,jit,numba,Python,Numpy,Jit,Numba,我今天开始使用numba,主要是因为我有一个嵌套的for循环,使用常规python代码可能需要很长时间 我有一个macports版本的python-2.7和llvm-3.6,还有一个pip版本的numba(一切都是最新的) 以下是我正在使用的代码: import pandas as pd from numba import jit from numpy import nan, full @jit def movingAverage(adj_close, maxMA): ma = ful
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
,一个将要计算的值的持有者。并分别计算出每天的VAULE(注意,第一天的平均值只能包括1天、第二天、2天,以此类推,直至最大值)
如果我输入类似于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开了一个网站。因此,我接受@MSeifert answer作为解决问题的方法。我认为
numba
在这里做了一些奇怪的事情,但可能是因为python
和nopython
模式的混合。如果我使用Python3.5,则返回值与使用和不使用print
的返回值相同
对于Python2.7,我认为问题在于For循环要么是在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.]])
然而,由于重新计算
len(adj_close)+1
,因此这不是一种非常有效的方法。这可能存储在某个地方。在我看来像个bug。我想在github上发布一些关于Numba问题的文章,因为您有一个演示这个问题的最小示例。不幸的是,我在运行它时得到了正确的答案(Python3,可能还有一个不同版本的Numba)。但是,我想知道将索引行更改为ma[d-1,I]=…
是否会有所帮助。我认为@MSeifert对python与nopython模式的比较是正确的,我记得nopython模式不能很好地处理顺序(即[a][b]
)索引。如果d==len(adj_close)+1:我可以使用如果d==ind[-1]
来获得相同的结果,而无需重新计算,我已经编辑了答案,我不知道这样的列表查找是否比计算快,但它看起来更快,尤其是对于小输入。对于len(adj_close)
和maxMA=1000
,典型值的顺序是200.000。为此,如果d==ind[-1](与在其他地方存储相同),则使用运行需要16分钟,如果d==len(adj_close)+1运行需要20分钟