Reputation: 21552
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
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
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
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
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
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