繁体   English   中英

numpy-使用先前值进行数组加法

[英]Numpy - Array addition using previous value

这就是我编写代码的方式,其中“分钟”和“差事”是相同大小的列表(下面的示例)。

但是相反,它们是两个numpy数组,因此此代码不起作用。 另一件事是我希望结果“完成”也是一个numpy数组。

done = 0
for i in minute:
    if done < minute:
        done = minute + (errands * 2)
    else:
        done = done + (errands * 2)
    print (done)

因此,我也尝试使用“ np.where”

import numpy as np
done = 0
done = np.where(done < minute, minute + (errands * 2), done + (errands * 2))
print(done)

这将是完美的,但是这里的问题是它不会连续更新“ done”,因此在某些时候将运行“ done = done +(errands * 2)”的等效代码(如果有意义)。

numpy数组的一些小例子:

minute = np.array([2, 2, 5, 5, 6, 7, 9, 11, 15])

errands = np.array([1, 1, 1, 7, 2, 2, 1, 1, 1])

只是为了让我尽可能清楚,我希望“ done”的输出是

done = np.array([4, 6, 8, 22, 26, 30, 32, 34, 36])

在此先感谢您的帮助。

由于更新,这是一个迭代问题。 但是,它是O(n),可以使用numbanjit有效地完成:

设定

from numba import njit

您可能需要pip install numba


@njit
def toggle(a, b):
    done, out = 0, []    
    for i in range(len(a)):
        if done < a[i]:
            done = a[i] + (b[i] * 2)
        else:
            done = done + (b[i] * 2)
        out.append(done)
    return np.array(out)

toggle(minute, errands)

array([ 4,  6,  8, 22, 26, 30, 32, 34, 36], dtype=int64)

性能

minute = np.repeat(minute, 10000)
errands = np.repeat(errands, 10000)

%timeit toggle(minute, errands)
2.02 ms ± 9.84 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

%timeit toggle_no_njit(minute, errands)
64.4 ms ± 738 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

可以单独使用numpy来完成:

def smart(m, e):
    e = 2*e
    r = np.empty(e.size+1, e.dtype)
    r[0] = 0
    e.cumsum(out=r[1:])
    return r[1:] + np.maximum.accumulate(m - r[:-1])

测试和时间安排:设置大小为1000的随机问题:

>>> e = np.random.uniform(1, 3, 1000)
>>> m = np.random.uniform(1, 7, 1000).cumsum()

给出与numba相同的结果:

>>> np.allclose(toggle(m, e), smart(m, e))
True

但是,即使不包括编译时间,速度也要快得多:

>>> timeit(lambda: toggle(m, e))
21.466296120896004
>>> timeit(lambda: smart(m, e))
11.608282678993419

您可以使用Numba非常有效地完成此任务。

但是请避免使用列表,就像@ user3483203在回答中所做的那样。 由于Numba无法直接处理列表2.6.2.4.1 ,因此列表的开销非常高 列表反射

@nb.njit
def toggle_2(a, b):
    done=0.
    out=np.empty(a.shape[0],dtype=a.dtype)

    for i in range(a.shape[0]):
        if done < a[i]:
            done = a[i] + (b[i] * 2)
        else:
            done = done + (b[i] * 2)
        out[i]=done
    return out

性能

e = np.random.uniform(1, 3, 1_000)
m = np.random.uniform(1, 7, 1_000).cumsum()

Paul Panzer (smart) : 13.22 µs
user3483203 (toggle): 18.47 µs
toggle_2              2.47  µs

e = np.random.uniform(1, 3, 1_000_000)
m = np.random.uniform(1, 7, 1_000_000).cumsum()

Paul Panzer (smart) : 15.97 ms
user3483203 (toggle): 30.28 ms
toggle_2              3.77  ms

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM