Convenient way of copying a sequence into an array axis if they differ in length?

Viewed 54

Hello fellow programmers!

I want to copy a sequence of length 3 into an array of dimensions 4x5:

import numpy as np


ar = np.zeros((4, 5))
print(ar)

data = [1,2,3]
ar[0] = data
print(ar)

Output:

[[0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0.]]

Error:

    ar[0] = data
ValueError: cannot copy sequence with size 3 to array axis with dimension 5

I was hoping to find a convenient way to get this output:

[[1. 2. 3. 0. 0.]
 [0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0.]]

without having to loop through each array element. Is there a way to do this?

Thank you in advance.

4 Answers

You want this!

ar[0, range(len(data))] = data 

ar
array([[1., 2., 3., 0., 0.],
       [0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0.]])

Note: Will throw IndexError if the data length is more than second dim in the array.

You can do this with ar[0][:3]

import numpy as np


ar = np.zeros((4, 5))
print(ar)

data = [1,2,3]
ar[0][:3] = data
print(ar)

[[0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0.]]
[[1. 2. 3. 0. 0.]
 [0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0.]]

You can use

ar[0][:len(data)] = data

if you know that data will be shorter than the first dimension of ar.

If data might be longer than this, you can make the desired 2D array with:

d = np.array(data)
d.resize((4,5))
print(d)

Note that d.resize(shape) pads with zeroes whereas np.resize(d,shape) would repeat the elements of d until the array is full.

Although Dishin Ha Goyani gave the correct answer to this question I wanted to give further insight on the same problem with more dimensional arrays.

The Original Problem was that I wanted to copy an array of dimensions (39, 7, 242) into an array of dimensions (4, 39, 12, 242) with length differences lying at 7 and 12.

The best I could come up with is this:

import numpy as np

ar = np.zeros((4, 39, 12, 242))
data = np.ones((39, 7, 242))

for idx_1, layer_1 in enumerate(ar):
    for idx_2, layer_2 in enumerate(layer_1):
        ar[idx_1][idx_2][range(len(data[idx_2]))] = data[idx_2]
Related