如何优化使用Numpy的连续值的for循环?

Est*_*oza 6 python numpy vectorization

我试图创建一个返回的功能numpy.arrayn0和1所使用的方法的细节之间的伪随机均匀分布的数字可以在这里找到:https://en.wikipedia.org/wiki/Linear_congruential_generator

到目前为止,效果很好。唯一的问题是,每个新值都是通过使用先前的值来计算的,因此,到目前为止,我发现的唯一解决方案是使用循环,为了提高效率,我尝试摆脱循环,可能是通过向量化操作-但是,我不知道该怎么做。

您对如何优化此功能有任何建议?

import numpy as np
import time

def unif(n):
    m = 2**32
    a = 1664525
    c = 1013904223

    result = np.empty(n)
    result[0] = int((time.time() * 1e7) % m)

    for i in range(1,n):
        result[i] = (a*result[i-1]+c) % m

    return result / m
Run Code Online (Sandbox Code Playgroud)

Ale*_*der 5

尽管没有向量化,但我相信以下解决方案的速度要快大约2倍(numba解决方案的速度要快60倍)。它将每个保存result为局部变量,而不是按位置访问numpy数组。

def unif_improved(n):
    m = 2**32
    a = 1664525
    c = 1013904223

    results = np.empty(n)
    results[0] = result = int((time.time() * 1e7) % m)

    for i in range(1, n):
        result = results[i] = (a * result + c) % m

    return results / m
Run Code Online (Sandbox Code Playgroud)

您也可以考虑使用Numba来进一步提高速度。https://numba.pydata.org/

仅仅添加装饰器就可以@jit吹开其他解决方案的门。

from numba import jit

@jit
def unif_jit(n):
    # Same code as `unif_improved`
Run Code Online (Sandbox Code Playgroud)

时机

>>> %timeit -n 10 unif_original(500000)
715 ms ± 21.5 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

>>> %timeit -n 10 unif_improved(500000)
323 ms ± 8 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

>>> %timeit -n 10 unif_jit(500000)
12 ms ± 2.68 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
Run Code Online (Sandbox Code Playgroud)