是否有某种方法可以避免此代码中的for
循环:
X = numpy array ~8000 long
running_total = 0
for x in X:
this_step = min(x, running_total)
running_total += this_step
用文字表示,计算一系列的累积和,其中样本之间的差异限于累积和的先前值。有没有办法使用numpy的元素操作来做到这一点?或者,如果我关心它的运行速度,我是否应该编写C函数?
编辑显然我没有说清楚。我试图简化上面的代码似乎比其他任何东西都引起了更多的困惑。这里有一些更接近实际代码的东西:
monthly_income = numpy array ~ 8000 long
monthly_expenditure = numpy array ~ 8000 long
running_credit = numpy.zeros(len(monthly_income) + 1)
monthly_borrowing = numpy.zeros(len(monthly_income))
for index, i, e in zip(range(len(monthly_income)), monthly_income, monthly_expenditure):
assets_used = max(0, e - i)
assets_used = min(assets_used, running_credit[index])
monthly_borrowing[index] = max(0, e - i - running_credit[index])
running_credit[index+1] += max(0, i - e) - assets_used
重点是running_index[index+1]
取决于样本assets_used
上的index
,这取决于running_credit[index]
。在Python循环中执行此操作很慢 - 在使用NumPy操作对相同输入数组执行许多类似计算的函数中,上述循环占用了80%的执行时间。但是如果没有for循环,我就无法看到进行上述操作的方法。
那么有没有一种方法可以在没有for循环的情况下在NumPy中进行这种迭代操作?或者,如果我想要快速运行,我是否需要编写C函数?
答案 0 :(得分:1)
最容易快速解决这类问题,我发现是使用numba。 E.g。
from numba import jit
import numpy as np
def cumsumcapped(X):
running_total = 0
for x in X:
this_step = min(x, running_total)
running_total += this_step
@jit
def cumsumcappedjit(X):
running_total = 0
for x in X:
this_step = min(x, running_total)
running_total += this_step
X = np.random.randint(1, 100, 10000)
In [5]: %timeit cumsumcapped(X)
100 loops, best of 3: 4.1 ms per loop
In [6]: %timeit stack.cumsumcappedjit(X)
The slowest run took 170143.03 times longer than the fastest. This could mean that an intermediate result is being cached.
1000000 loops, best of 3: 587 ns per loop
答案 1 :(得分:0)
不确定但是从你的解释中猜测(假设x是非负的)
X = [1 ... 999]
running_total = X[0]
for x in X[1:]:
this_step = min(x, running_total)
running_total += this_step