如何有效地制作一个大的numpy数组

时间:2015-07-16 15:18:32

标签: python numpy

即使是n,我也希望通过3^(n/2)-1 2d-numpy数组生成n。每一行的前半部分应迭代所有可能的-1,0,1值,后半部分应为零。但是,上半部分永远不应该全为零。

这个代码几乎可以工作,除了它包含我不想要的所有零行。

n = 4
M = [list(row) +[0]*(n/2) for row in itertools.product([-1,0,1], repeat = n/2)]
print np.array(M)

它给出了

[[-1 -1  0  0]
 [-1  0  0  0]
 [-1  1  0  0]
 [ 0 -1  0  0]
 [ 0  0  0  0]
 [ 0  1  0  0]
 [ 1 -1  0  0]
 [ 1  0  0  0]
 [ 1  1  0  0]]

是否有一种不太可怕且时间和空间效率更高的方法来做到这一点? n最终将为30,我当然不会将其打印出来。 3 ^ 15仅为14,348,907但是当我设置n=30并且花费很长时间时,代码使用我的8GB机器上的所有RAM。

如何直接制作numpy数组而不通过itertools,list等。?

1 个答案:

答案 0 :(得分:5)

这将创建您的数组,而无需任何大的辅助内存分配:

n = 30
assert 2 * (n // 2) == n
rows = 3**(n//2)
cols = n

arr = np.zeros((rows, cols), dtype=int)
shape = (rows,)

source = np.array([-1, 0, 1], dtype=np.int)[:, None]

for col in range(n//2):
    shape = (-1, 3, shape[-1]//3,)
    col_view = arr[:, col]
    col_view.shape = shape
    col_view[:] = source

在我的笔记本电脑上完成大约需要10秒钟。它基于this great answer松散地基于类似的问题。

使用这种方法不能轻易做到的是在构造过程中摆脱零中间线,因为它是算法工作的核心。你可以随后摆脱它:

arr = np.delete(arr, rows//2, axis=0)

但是这将分配一个新数组并将内容复制到它之后再丢弃旧数组,因此你的内存需求会突然加倍。

用Python或NumPy想不出任何简单快捷的方法。