【问题标题】:avoid for loop in python normal(size={}))避免python中的for循环正常(size = {}))
【发布时间】:2020-10-21 21:43:13
【问题描述】:

我的目标是创建一个数组,其中每个元素是normal(size={})) 的每个it 元素。

我正在尝试优化:

it = 2 ** arange(6, 25)
M = zeros(len(it))
for x in range(len(it)):
    M[x] = (normal(size=it[x]))

到目前为止我还没有这些工作:

N = zeros(len(it))
it = 2 ** arange(6, 25)
N = (normal(size=it))

我进一步尝试:

N = (normal(size=it[:]))

提供我的数据,我相信这样的手动工作,或者for循环确实效率低下,所以我正在尝试想出向量化的操作。

我收到:

File "mtrand.pyx", line 1335, in numpy.random.mtrand.RandomState.normal
  File "common.pyx", line 557, in numpy.random.common.cont
ValueError: array is too big; `arr.size * arr.dtype.itemsize` is larger than the maximum possible size.

【问题讨论】:

  • 如果您将 25 更改为较小的数字可能会有所帮助,例如10

标签: python numpy loops vector random


【解决方案1】:

您对这些函数的来源不是很准确,但我猜normal(size=it[:]) 您的意思是:

import numpy as np
it = 2 ** np.arange(6, 25)
np.random.normal(size=it)

这将告诉 numpy 创建一个 19 维数组(即 len(it)),其中包含 6 × 1085 个元素(即 np.prod(it.astype(float)) 作为浮点数,因为数字溢出 int64)。 numpy 说它不能那样做,这似乎是一件合理的事情。

Numpy 不喜欢您尝试创建的 "ragged arrays",大多数矩阵/数字库也不喜欢,因此支持有限!

我不确定您为什么认为“循环确实效率低下”。你从一个简单的 Python 循环的 19 次迭代中创建了大约 3300 万个浮点数。 大量大部分时间将花在高度优化的 Numpy 库代码上,而一小部分(基本上无法衡量)的时间将花在评估 Python 字节码上。

如果你真的想要单线,那么你可以这样做:

X = [np.random.normal(size=2**i) for i in range(6, 25)]

这使得 Numpy 和 Python 世界之间的区别更加明显。

请注意,在我的笔记本电脑上,Python 代码的执行时间约为 5µs,而 Numpy 代码的运行时间约为 800ms。所以你正在尝试优化 0.0006% 的部分!

请注意,使用 Numpy 的向量化并不总是一种胜利,它只对更大的数组有帮助,例如,上面的循环比:

X = [np.random.normal(i) for i in 2**np.arange(6, 25)]

Python 代码为 4.8 与 5.1 µs,因为编组对象进出 Numpy 世界所花费的时间。同样,这些都不重要,只需使用使您的代码更易于理解的任何解决方案即可。与秒相比,几微秒微不足道。

【讨论】:

  • 谢谢,我的实际任务需要:for x in range(len(it)): M[x] = sum(normal(size=it[x])) 我知道这会改变问题,但仍然可能与提问有关。
猜你喜欢
  • 2017-08-27
  • 2017-11-11
  • 2022-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-20
相关资源
最近更新 更多