我的目标是创建一个数组,其中每个元素都是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 世界所花费的时间。 同样,这些都不重要,只需使用使您的代码更容易理解的解决方案即可。 与几秒钟相比,几微秒算不了什么。