【问题标题】:Is there a fast iterator over random numbers in python?python中的随机数是否有快速迭代器?
【发布时间】:2013-11-16 19:04:04
【问题描述】:

我在我的 python 脚本中使用了很多随机数。传统上,我只是在需要它们的地方调用 random.random(),但现在这占了执行时间的很大一部分。所以我想提高速度。

原始版本可以归结为:

from random import random
for _ in range(cycles):
    _ = random()

请注意,有一个固定的(当然更复杂的)迭代正在进行。

现在我尝试使用numpy

from numpy.random import random
for _ in range(cycles):
    _ = random()

一方面这比内置 random 还要慢,但另一方面 numpy.random.random 支持生成大量随机数:

from numpy.random import random
rnd = random(cycles)
i = 0
for _ in range(cycles):
    _ = rnd[i]
    i += 1

太棒了!这只有原始运行时间的大约 五分之一

我的问题是,维护单独的索引i不是很好,所以我宁愿写这样的东西:

from numpy.random import random
from numpy import nditer
iter_rnd = nditer(random(cycles))
for _ in range(cycles):
    _ = next(iter_rnd)

不幸的是,这与前两个版本一样慢。生成器表达式和函数更糟糕。那么有没有更优雅、更快速的东西呢?

【问题讨论】:

  • 最佳加速(最高 1000 倍)将来自用 numpy 矢量化操作替换迭代。如果你能做到,那就去做。如果您发布更多关于您使用这些数字做什么的详细信息,我们或许可以帮助您做到这一点。
  • 在此期间,您是否尝试过 enumerating 数组?
  • @user2357112:感谢您的建议。进行矢量化操作确实是一个有趣的想法。但这需要对算法进行重大重建。我一定会考虑的。
  • @user2357112:使用枚举又慢了。这么简单的事情怎么会增加这么多(相对的)开销,真是令人沮丧……
  • 你在循环体中做了多少工作?贴出代码;几乎可以肯定它很短。我们现在或许可以对其进行矢量化处理。

标签: python performance random python-3.x iterator


【解决方案1】:
for i, random_number in enumerate(rnd):
    do_whatever(i, random_number)

enumerate 是您想要迭代序列及其索引时使用的常用工具。但是,如果您使用的是 numpy,通常最好尽可能避免迭代。用 numpy 向量化操作代替迭代可以使您的代码更短、更简洁,并且速度提高多达 1000 倍。

说到这里,我想指出一些我在您使用 for 循环时注意到的奇怪之处。

from numpy.random import random
rnd = random(cycles)
i = 0
for _ in range(cycles):
    _ = rnd[i]
    i += 1

您似乎使用for 循环作为重复代码体一定次数的一种方式,完全忽略了迭代变量。 for _ in range(cycles) 已经迭代了从 0cycles - 1 的整数;您不需要手动增加单独的 i 变量。这段代码可以简化为:

from numpy.random import random
rnd = random(cycles)
for i in range(cycles):
    random_number = rnd[i]

【讨论】:

  • 您当然是正确的,代码可以在那里简化。但我想说明,有一个固定的迭代(尽管更复杂和嵌套)正在进行,它独立于随机数,就像在最初的例子中一样。
【解决方案2】:

如何使用内置的方式来遍历numpy数组,而不是nditer()?

from numpy.random import random
rnd = iter(random(cycles))
for _ in range(cycles):
    _ = rnd.next()

【讨论】:

  • 实际上我无法重现您提到的时间。对我来说,使用 numpy 的示例all比内置的 random 模块慢。
猜你喜欢
  • 2012-03-04
  • 2015-02-10
  • 2012-10-27
  • 1970-01-01
  • 2015-08-02
  • 2015-12-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多