避免在 Python normal(size={})) 中为 FOR 循环)



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

我正在尝试淡化:

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.

你对这些函数的来源不是很精确,但我猜

你的意思是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 不喜欢您尝试创建的"参差不齐的数组",大多数矩阵/数字库也不喜欢,因此支持有限!

我不确定你为什么认为"循环真的很低效"。 您正在从简单 Python 循环的 19 次迭代中创建 ~3300 万个浮点数。绝大多数时间将用于高度优化的 Numpy 库代码,并且一些微小的(基本上无法测量的)时间将用于评估您的 Python 字节码。

如果你真的想要一个单行,那么你可以做:

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

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

请注意,在我的笔记本电脑上,Python 代码在 ~5μs 内执行,而 Numpy 代码运行 ~800 毫秒。 因此,您正在尝试优化 0.0006% 的部分!

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

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

Python 代码为 4.8 与 5.1 μs,因为将对象编入/编组出 Numpy 世界所花费的时间。 同样,这些都不重要,只需使用使您的代码更容易理解的解决方案即可。 与几秒钟相比,几微秒算不了什么。

最新更新