即使是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等。?
答案 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想不出任何简单快捷的方法。