Fabio Lamanna
Fabio Lamanna

Reputation: 21552

numpy - resize array filling with 0

I have the following numpy array:

a = np.array([[1.1,0.8,0.5,0,0],[1,0.85,0.5,0,0],[1,0.8,0.5,1,0]])

with shape = (3,5).

I would like to reshape and resize it to a new array with shape = (3,8), filling the new values in each row with 0. So far I tried the following approach:

b = np.resize(a,(3,8))

But it returns:

[[ 1.1   0.8   0.5   0.    0.    1.    0.85  0.5 ]
 [ 0.    0.    1.    0.8   0.5   1.    0.    1.1 ]
 [ 0.8   0.5   0.    0.    1.    0.85  0.5   0.  ]]

instead of the expected (for me):

[[ 1.1   0.8   0.5   0.    0.    0.    0.    0. ]
 [ 1.    0.85  0.5   0.    0.    0.    0.    0. ]
 [ 1.    0.8   0.5   1.    0.    0.    0.    0. ]]

Upvotes: 14

Views: 28593

Answers (5)

GabrielChu
GabrielChu

Reputation: 6156

Definitely you can use resize().

If the new array is larger than the original array, then the new array is filled with repeated copies of a. Note that this behavior is different from a.resize(new_shape) which fills with zeros instead of repeated copies of a.

b = a.transpose().copy()
b.resize((8,3), refcheck=False)
b = a.transpose()

which outputs:

[[ 1.1   0.8   0.5   0.    0.    0.    0.    0.  ]
 [ 1.    0.85  0.5   0.    0.    0.    0.    0.  ]
 [ 1.    0.8   0.5   1.    0.    0.    0.    0.  ]]

Limitation:

Filling with 0s can be only applied to the 1st dimension.

Upvotes: 9

Divakar
Divakar

Reputation: 221524

Use np.lib.pad -

np.lib.pad(a, ((0,0),(0,3)), 'constant', constant_values=(0))

Sample run -

In [156]: a
Out[156]: 
array([[ 1.1 ,  0.8 ,  0.5 ,  0.  ,  0.  ],
       [ 1.  ,  0.85,  0.5 ,  0.  ,  0.  ],
       [ 1.  ,  0.8 ,  0.5 ,  1.  ,  0.  ]])

In [157]: np.lib.pad(a, ((0,0),(0,3)), 'constant', constant_values=(0))
Out[157]: 
array([[ 1.1 ,  0.8 ,  0.5 ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ],
       [ 1.  ,  0.85,  0.5 ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ],
       [ 1.  ,  0.8 ,  0.5 ,  1.  ,  0.  ,  0.  ,  0.  ,  0.  ]])

Runtime tests -

This section covers runtime tests for the approaches posted thus far for the size listed in the question and scaling it up by 100x. Here are the timing test results -

In [212]: def init_based(a,N):
     ...:   b = np.zeros((a.shape[0], a.shape[1]+N))
     ...:   b[:, :a.shape[1]] = a
     ...:   return b
     ...: 

In [213]: a = np.random.rand(3,5)

In [214]: N = 3

In [215]: %timeit np.lib.pad(a, ((0,0),(0,N)), 'constant', constant_values=(0))
     ...: %timeit np.hstack([a, np.zeros([a.shape[0], N])])
     ...: %timeit np.concatenate((a,np.zeros((a.shape[0],N))), axis=1)
     ...: %timeit init_based(a,N)
     ...: 
10000 loops, best of 3: 32.7 µs per loop
100000 loops, best of 3: 11.2 µs per loop
100000 loops, best of 3: 4.49 µs per loop
100000 loops, best of 3: 5.67 µs per loop

In [216]: a = np.random.rand(300,500)

In [217]: N = 300

In [218]: %timeit np.lib.pad(a, ((0,0),(0,N)), 'constant', constant_values=(0))
     ...: %timeit np.hstack([a, np.zeros([a.shape[0], N])])
     ...: %timeit np.concatenate((a,np.zeros((a.shape[0],N))), axis=1)
     ...: %timeit init_based(a,N)
     ...: 
100 loops, best of 3: 2.99 ms per loop
1000 loops, best of 3: 1.72 ms per loop
1000 loops, best of 3: 1.71 ms per loop
1000 loops, best of 3: 1.72 ms per loop

Upvotes: 23

Hackaholic
Hackaholic

Reputation: 19733

np.concatenate

np.concatenate((a,np.zeros((3,3))), axis=1)
array([[ 1.1 ,  0.8 ,  0.5 ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ],
       [ 1.  ,  0.85,  0.5 ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ],
       [ 1.  ,  0.8 ,  0.5 ,  1.  ,  0.  ,  0.  ,  0.  ,  0.  ]])

Upvotes: 3

P. Camilleri
P. Camilleri

Reputation: 13218

From the doc of np.resize():

If the new array is larger than the original array, then the new array is filled with repeated copies of a.

Zeros are not used, but actual values of a.

Instead, you could use np.hstack() and np.zeros() :

np.hstack([a, np.zeros([3, 3])])

Edit: I have not tested the speed, so I suggest you have a look a other solutions too.

Upvotes: 9

Leo
Leo

Reputation: 1107

Another option (although np.hstack is probably best as in M. Massias' answer).

Initialise an array of zeros:

b = np.zeros((3, 8))

Fill using slice syntax:

b[:3, :5] = a

Upvotes: 5

Related Questions