Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

np.reshape() with padding if there are not enough elements

Is it possible to reshape a np.array() and, in case of inconsistency of the new shape, fill the empty spaces with NaN?

Ex:

arr = np.array([1,2,3,4,5,6])

Target, for instance a 2x4 Matrix:

[1 2  3   4]
[5 6 NaN NaN]

I need this to bypass the error: ValueError: cannot reshape array of size 6 into shape (2,4)

like image 367
heresthebuzz Avatar asked Jun 18 '20 21:06

heresthebuzz


People also ask

What is use of reshape () method in the NumPy?

NumPy: reshape() function The reshape() function is used to give a new shape to an array without changing its data. Array to be reshaped. The new shape should be compatible with the original shape. If an integer, then the result will be a 1-D array of that length.

What is the difference between reshape () and resize ()?

resize() methods are used to change the size of a NumPy array. The difference between them is that the reshape() does not changes the original array but only returns the changed array, whereas the resize() method returns nothing and directly changes the original array.

What is the use of reshape () method?

Reshaping means changing the shape of an array. The shape of an array is the number of elements in each dimension. By reshaping we can add or remove dimensions or change number of elements in each dimension.


Video Answer


3 Answers

We'll use np.pad first, then reshape:

m, n = 2, 4
np.pad(arr.astype(float), (0, m*n - arr.size), 
       mode='constant', constant_values=np.nan).reshape(m,n)


array([[ 1.,  2.,  3.,  4.],
       [ 5.,  6., nan, nan]])

The assumption here is that arr is a 1D array. Add an assertion before this code to fail on unexpected cases.

like image 96
cs95 Avatar answered Oct 22 '22 18:10

cs95


Lots of ways of doing this, but (nearly) all amount to creating a new array of the desired shape, and filling values:

In [50]: arr = np.array([1,2,3,4,5,6])                                          
In [51]: res = np.full((2,4), np.nan)                                           
In [52]: res                                                                    
Out[52]: 
array([[nan, nan, nan, nan],
       [nan, nan, nan, nan]])
In [53]: res.flat[:len(arr)]=arr                                                
In [54]: res                                                                    
Out[54]: 
array([[ 1.,  2.,  3.,  4.],
       [ 5.,  6., nan, nan]])

I used flat to treat res as a 1d array for copy purposes.

An exception is the resize method, but that fills with 0s. And doesn't change the dtype to allow for float nan:

In [55]: arr.resize(2,4)                                                        
In [56]: arr                                                                    
Out[56]: 
array([[1, 2, 3, 4],
       [5, 6, 0, 0]])
like image 32
hpaulj Avatar answered Oct 22 '22 18:10

hpaulj


One possible solution :

convert array to float (nan is a float type)

arr = np.array([1,2,3,4,5,6]).astype(float)

resize data to new shape

arr = np.resize(arr, (2,4))

print(arr)

array([[1., 2., 3., 4.],
   [5., 6., 1., 2.]])

replace last two entries with np.NaN

arr[-1,-2:] = np.NaN

print(arr)

array([[ 1.,  2.,  3.,  4.],
       [ 5.,  6., nan, nan]])
like image 2
sammywemmy Avatar answered Oct 22 '22 18:10

sammywemmy