NumPy Array Reshape and Resize

NumPy has two functions (and also methods) to change array shapes - reshape and resize. They have a significant difference that will our focus in this chapter.

numpy.reshape()

Let’s start with the function to change the shape of array - reshape().

import numpy as np

arrayA = np.arange(8)
# arrayA = array([0, 1, 2, 3, 4, 5, 6, 7])

np.reshape(arrayA, (2, 4))
#array([[0, 1, 2, 3],
#       [4, 5, 6, 7]])

It converts a vector of 8 elements to the array of the shape of (4, 2). It could be executed successfully because the amount of elements before and after reshape is identical. It raises ValueError if the amounts are different.

In [1]: np.reshape(arrayA, (3, 4))
    ---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
ValueError: cannot reshape array of size 8 into shape (3,4)

Let’s take a closer look of the reshaped array. The first row is the first 4 data of arrayA and the second row takes the last 4. It fills the data in the order of row in this reshape conversion.

You need to change the parameter order if you want the order of filling data to be column.

In [1]: np.reshape(arrayA, (2, 4), order='F')
Out[1]: array([[0, 2, 4, 6],
        	  [1, 3, 5, 7]])

The default of order is C that means to read or write data in C-like index order, or in simple words, in the order of row. F means to read or write data in Fortan-like index order, or let’s say, in the order of column. You could refer to official NumPy documentation to know more details of different indexing methods.

ndarray.reshape()

Besides the reshape function, NumPy has also reshape method in the ndarray object. The method has the same parameters as the function but without given array as a parameter.

In [1]: arrayB = arrayA.reshape((2, 4))
    
In [2]: arrayB
Out[2]:	array([[0, 1, 2, 3],
       		[4, 5, 6, 7]])
In [1]: arrayA
Out[2]: array([0, 1, 2, 3, 4, 5, 6, 7])    

You could see, reshape method is similar to reshape function. And you should also be aware that ndarray.reshape() method doesn’t change data and shape of the original array but returns a new ndarray instance.

reshape() Function/Method Shared Memory

The converted array in reshape function or method shares the same memory of the original array. You could think it as shallow copy in Python, where if you change the data in one array, the corresponding data in the other array is also modified.

In [1]: arrayA = np.arange(8)
    	arrayB = arrayA.reshape((2, 4))
        arrayB
Out[2]:	array([[0, 1, 2, 3],
       		[4, 5, 6, 7]])
In [2]: arrayA[0] = 10
    	arrayA
Out[2]: array([10, 1, 2, 3, 4, 5, 6, 7]) 
In [3]: arrayB    
Out[3]:	array([[10, 1, 2, 3],
       		[4, 5, 6, 7]])    

numpy.resize()

numpy.resize() is a bit similar to reshape in the sense of shape conversion. But it has some significant differences.

  1. It doesn’t have order parameter. The order of resize is the same as order='C' in reshape.
  2. If the number of elements of target array is not the same as original array, it will force to resize but not raise errors.

Let’s focus on the second difference.

In [1]: arrayA = np.arange(8)
        arrayB = np.resize(arrayA, (2, 4))
Out[1]: array([[0, 1, 2, 3],
       [4, 5, 6, 7]])

The result is the same as that in reshpae if the element numbers are the same.

In [1]: arrayC = np.resize(arrayA, (3, 4))
    	arrayC
Out[1]: array([[0, 1, 2, 3],
       [4, 5, 6, 7],
       [0, 1, 2, 3]])
In [2]: arrayD = np.resize(arrayA, (4, 4))
    	arrayD
Out[2]: array([[0, 1, 2, 3],
       [4, 5, 6, 7],
       [0, 1, 2, 3],
       [4, 5, 6, 7]])

If the new array has more rows, it will repeat the data in the original array but not raise the error.

In [1]: arrayE = np.resize(arrayA, (2, 2))
		arrayE
Out[1]: array([[0, 1],
       [2, 3]])    
In [2]: np.resize(arrayA, (1,4))
Out[2]: array([[0, 1, 2, 3]])

If the number of elements in the new array is smaller, it fetches the number of elements it needs to fill in the new array in the order of row.

resize Function/Method Memory

The new array doesn’t share the same memory with the original array in resize function/method. The data change in one array is not mapped to the other.

In [1]: arrayA = np.arange(8)
    	arrayB = arrayA.reshape((2, 4))
        arrayB
Out[2]:	array([[0, 1, 2, 3],
       		[4, 5, 6, 7]])
In [2]: arrayA[0] = 10
    	arrayA
Out[2]: array([10, 1, 2, 3, 4, 5, 6, 7]) 
In [3]: arrayB    
Out[3]:	array([[0, 1, 2, 3],
       		[4, 5, 6, 7]])