NumPy:有限累积金额

时间:2016-09-20 16:38:10

标签: python numpy

是否有某种方法可以避免此代码中的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函数?

2 个答案:

答案 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
相关问题