How to efficiently make an array with a lot

Given an even n, I would like to make a 3^(n/2)-1

by n

2d-numpy array . The first half of each line should iterate over all possible values ​​-1,0,1, and the second half should be zero. However, the first half should never contain all zeros.

This code almost works, except it includes the entire null string, which I don't want.

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

      

He gives

[[-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]]

      

Is there a less awful and more efficient time and space for this? n

will eventually be 30, and I will not print it, of course. 3 ^ 15 is only 14,348,907, but the code is using all the RAM on my 8GB computer when I installed n=30

and also took a very long time.

How can I make a numpy array directly without going through itertools, lists, etc.?

+3


source to share


1 answer


This will create your array without requiring a lot of auxiliary memory allocation:

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

      

Ends on my laptop in about 10 seconds. This is loosely based on this excellent answer to a similar question.

What is easy to do with this approach is to get rid of the centerline of zeros during plotting, as it is central to the algorithm's operation. You can always get rid of it:



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

      

But this will allocate a new array and copy its contents before discarding the old one, so your memory requirements will suddenly double.

Couldn't find a quick and fast way easily with Python or NumPy.

+5


source







All Articles