Python 3.x 用python生成大量随机数

Python 3.x 用python生成大量随机数,python-3.x,numpy,random,Python 3.x,Numpy,Random,我想生成随机数,均匀地在-1和1之间。 我知道使用NumPy并生成一个数字数组比在for循环中逐个生成要好得多。 另一方面,我希望这些数字只使用它们一次,所以没有理由将它们存储在数组中。 我的问题是,什么是最好的解决方案,一方面,使用for循环没有时间效率,但我不存储不必要的数字,我一个接一个地生成它们,然后抛出它们。另一方面,数组的内存效率不高,因为如果我想生成10^10个数字,我需要创建一个10^10大小的数组,结果会很糟糕。 我认为最好的选择是一个接一个地生成小数组(10^3或10^4个元

我想生成随机数,均匀地在-1和1之间。 我知道使用NumPy并生成一个数字数组比在for循环中逐个生成要好得多。 另一方面,我希望这些数字只使用它们一次,所以没有理由将它们存储在数组中。 我的问题是,什么是最好的解决方案,一方面,使用for循环没有时间效率,但我不存储不必要的数字,我一个接一个地生成它们,然后抛出它们。另一方面,数组的内存效率不高,因为如果我想生成10^10个数字,我需要创建一个10^10大小的数组,结果会很糟糕。
我认为最好的选择是一个接一个地生成小数组(10^3或10^4个元素),但我想知道是否有更好的解决方案来解决这个问题(可能是一个NumPy函数,它生成数字,但创建一个类似iterable的东西,它不会将所有的数字都存储在内存中?

你可以制作一个生成器,正如@Carcigenicate在评论中所说的,并将其与使用表达式的收益率生成整个数组的速度相结合

这看起来像这样:

def random_number():
尽管如此:
np.random.random(1000)*2-1的收益率

您可以根据需要调整一次生成的值的数量,越大越快,但使用的内存越多使用NumPy生成数字块是最好的,并且您希望尽可能保持操作矢量化

一个简单的基准测试表明,4k和64k之间的某个地方是一个合理的块大小:

from timeit import Timer
import numpy as np

for xp in range(20):
    size = 2**xp
    timer = Timer(
        f'rng.uniform(-1., 1., size={size})',
        'rng = np.random.default_rng()',
        globals=globals()
    )
    n, t = timer.autorange()
    t = min([t] + timer.repeat(3, n)) / n / size
    print(f'{size:8} = {1e-6/t:6.2f}M/s')
给我

1=0.47M/s
2=0.95M/s
4=1.89M/s
8=3.80M/s
16=7.43M/s
32=14.26M/s
64=27.10M/s
128=48.60M/s
256=78.72M/s
512=119.07M/s
1024=158.71M/s
2048=191.51米/秒
4096=218.71M/s
8192=233.25M/s
16384=241.23M/s
32768=245.35M/s
65536=248.75M/s
131072=250.53M/s
262144=252.62M/s
524288=253.99M/s
以矢量形式处理数字的速度要快几个数量级。 例如,给定一个64k值数组,
np.sum(x)
的向量化调用需要17µs,而类似版本通过生成器
sum(x)
需要3.5ms,即慢200倍。一旦你付出了代价,让浮点数进入非矢量化的Python世界,通过另一个
获得的收益没有多大区别,只需要4.5ms,例如:通过iPython
%timeit
魔术:

def yield_from(it):
    yield from it

x = np.random.uniform(-1, 1, size=2**16)

%timeit np.sum(x)
%timeit sum(x)
%timeit sum(yield_from(x))

如果您不需要存储结果,您可以使用一个生成器函数,该函数可以根据需要生成随机数。这比不使用任何外部函数逐个生成随机数快吗?