Ulysses
Ulysses

Reputation: 357

Numpy: copying an array to more dimensions

I am given a 1-dimensional array g and I would like to create an m-dimensional array a such that

a[i1][i2]...[im][im] = g[im]

for all choices of indices. A naive code for the case m = 2 is:

import numpy as np

g = ones(3)
a = zeros((3,3))

a[:][:] = g

I would expect there is a much more elegant method, which also does not depend on the value of m.

Upvotes: 1

Views: 75

Answers (2)

Alex Riley
Alex Riley

Reputation: 176750

Unless I'm mistaken about what you're looking for, NumPy handles all the copying for you regardless of the number of dimensions. If the shapes of the two arrays are compatible, the code a[:] = g broadcasts the flat array g to a:

>>> a = np.zeros((3,3,3)) # a 3x3x3 array of zeros
>>> g = np.ones(3) # a row of 3 ones
>>> a[:] = g
>>> a
array([[[ 1.,  1.,  1.],
        [ 1.,  1.,  1.],
        [ 1.,  1.,  1.]],

       [[ 1.,  1.,  1.],
        [ 1.,  1.,  1.],
        [ 1.,  1.,  1.]],

       [[ 1.,  1.,  1.],
        [ 1.,  1.,  1.],
        [ 1.,  1.,  1.]]])

This will work whatever the dimensionality of a.

Regarding the earlier mention of compatibility: in this case the length of g must match the length of the trailing (i.e. last) dimension of a or else be of length 1 (so a[:] = 1 produces the same result as a[:] = g here).

In the case above, a has shape (3, 3, 3) and g has shape (3,) so the two are compatible. We could also have done the the same operation successfully if a had shape (2, 5, 5, 3) for example.

Upvotes: 1

Wolph
Wolph

Reputation: 80011

You are probably looking for the shape property, here are a few examples:

In [2]: import numpy as np

In [3]: g = np.arange(100)

In [4]: g
Out[4]:
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
       17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
       34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
       51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67,
       68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
       85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99])

In [5]: g.shape = 10, 10

In [6]: g
Out[6]:
array([[ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
       [20, 21, 22, 23, 24, 25, 26, 27, 28, 29],
       [30, 31, 32, 33, 34, 35, 36, 37, 38, 39],
       [40, 41, 42, 43, 44, 45, 46, 47, 48, 49],
       [50, 51, 52, 53, 54, 55, 56, 57, 58, 59],
       [60, 61, 62, 63, 64, 65, 66, 67, 68, 69],
       [70, 71, 72, 73, 74, 75, 76, 77, 78, 79],
       [80, 81, 82, 83, 84, 85, 86, 87, 88, 89],
       [90, 91, 92, 93, 94, 95, 96, 97, 98, 99]])

In [7]: g.shape = 2, 50

In [8]: g
Out[8]:
array([[ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
        17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
        34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49],
       [50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66,
        67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83,
        84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99]])

In [9]: g.shape = 5, 20

In [10]: g
Out[10]:
array([[ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
        17, 18, 19],
       [20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
        37, 38, 39],
       [40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
        57, 58, 59],
       [60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76,
        77, 78, 79],
       [80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96,
        97, 98, 99]])

In the case of a n=m^2 matrix you could do this:

g = ones(9)
a = g.reshape(np.sqrt(g.shape[0]), np.sqrt(g.shape[0]))

Alternatively, you could be looking for tile instead: http://docs.scipy.org/doc/numpy/reference/generated/numpy.tile.html

In which case it would be something like this:

np.tile(g, (m, 1))

Upvotes: 2

Related Questions