shape
attribute (in-place operation)np.reshape()
method (shallow copy)np.resize()
method (deep copy)ndarray.transpose()
method (shallow copy)np.swapaxes()
method (shallow copy)np.flatten()
method (deep copy)np.sort()
Method# To install this library in Jupyter notebook
#import sys
#!{sys.executable} -m pip install numpy
import numpy as np
np.__version__ , np.__path__
('1.19.5', ['/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/numpy'])
Review of Arithmetic operations with numPy arrays of same shape:
import numpy as np
# Create two 1-D arrays each having 4 random integers from 1 to 9
arr1 = np.random.randint(1,50, size=5)
arr2 = np.random.randint(1,10, size=5)
print("arr1: ", arr1)
print("arr2: ", arr2)
# After the operation a new `ndarray` is returned
print("arr1 + arr2 = ", arr1 + arr2)
print("arr1 / arr2 = ", arr1 / arr2)
print("arr1 // arr2 = ", arr1 // arr2)
print("arr1 ** arr2 = ", arr1 ** arr2)
arr1: [11 11 32 29 25] arr2: [7 9 1 7 4] arr1 + arr2 = [18 20 33 36 29] arr1 / arr2 = [ 1.57142857 1.22222222 32. 4.14285714 6.25 ] arr1 // arr2 = [ 1 1 32 4 6] arr1 ** arr2 = [ 19487171 2357947691 32 17249876309 390625]
# Consider adding a scalar value 'a' to a 1-D numPy array
arr1 = np.array([1, 2, 3, 4])
print("arr1: ", arr1)
print("arr1.shape: ", arr1.shape)
a = 2
print("a: ", a)
arr1: [1 2 3 4] arr1.shape: (4,) a: 2
# The scalar value is replicated to match the shape of arr1 before the operation
# [2 2 2 2]
arr2 = arr1 + a
print("arr2: \n", arr2)
arr2: [3 4 5 6]
# Consider adding a scalar value 'a' to a 2-D numPy array
arr1 = np.array([[1, 2, 3], [1, 2, 3]])
print("arr1:\n", arr1)
print("arr1.shape: ", arr1.shape)
a = 2
print("a: ", a)
arr1: [[1 2 3] [1 2 3]] arr1.shape: (2, 3) a: 2
# The scalar value is replicated to match the shape of arr1 before the operation
# 2 2 2
# 2 2 2
arr2 = arr1 + a
print("arr2: \n", arr2)
arr2: [[3 4 5] [3 4 5]]
Example 1: Consider adding a 2-D array (3x4) to a 1-D array with 4 values
arr1 = np.array([[1, 2, 3, 4], [3, 4, 5, 6], [2, 7, 8, 9]])
arr2 = np.array([4, 2, 3, 2])
print("arr1:\n", arr1)
print("arr1.shape: ", arr1.shape)
print("arr2:\n", arr2)
print("arr2.shape: ", arr2.shape)
arr1: [[1 2 3 4] [3 4 5 6] [2 7 8 9]] arr1.shape: (3, 4) arr2: [4 2 3] arr2.shape: (3,)
# The only row of arr2 is replicated twice before the operation
# 4 2 3 5
# 4 2 3 5
# 4 2 3 5
arr3 = arr1 + arr2
print("arr3: \n", arr3)
arr3: [[ 5 4 6 9] [ 7 6 8 11] [ 6 9 11 14]]
Example 2: Consider adding a 2-D array (4x2) to a 1-D array with 2 values
arr1 = np.array([[1, 2], [3, 4], [5, 6], [7, 8]])
print("arr1:\n", arr1)
print("arr1.shape: ", arr1.shape)
arr2 = np.array([4, 5])
print("arr2:\n", arr2)
print("arr2.shape: ", arr2.shape)
# The only row of arr2 is replicated three times before the operation
# 4 5
# 4 5
# 4 5
# 4 5
arr3 = arr2 + arr1
print("arr3: \n", arr3)
Example 1: Consider adding elements of a 2-D array (2x3) with another 2-D array (3x1)
arr1 = np.array([[5, 3, 2],[3, 4, 5], [7, 1, 4]])
print("arr1:\n", arr1)
print("arr1.shape: ", arr1.shape)
arr2 = np.array([[100], [200], [300]])
print("arr2:\n", arr2)
print("arr2.shape: ", arr2.shape)
# The only column of arr2 is replicated twice before the operation
# 100 100 100
# 200 200 300
# 300 300 300
arr3 = arr1 + arr2
print("arr3: \n", arr3)
Points to Ponder in Arithmetic and Broadcasting:
- Arithmetic between elements of two numPy arrays works fine if both the arrays are of same shape.
- Arithmetic between a numPy array and a scalar value works fine due to broadcasting.
- Arithmetic between elements of two numPy arrays with different dimensions will work, if and only if the array with smaller dimension can be replicated to match the shape of other array (as in above examples)
Example 1: Broadcast Error
# Consider adding a 2-D array (2x3) to a 1-D array with 2 values
arr1 = np.array([[1, 2, 3], [1, 2, 3]])
arr2 = np.array([1,2])
print("arr1:\n", arr1)
print("arr1.shape: ", arr1.shape)
print("arr2:\n", arr2)
print("arr2.shape: ", arr2.shape)
arr1: [[1 2 3] [1 2 3]] arr1.shape: (2, 3) arr2: [1 2] arr2.shape: (2,)
# Since arr2 cannot be replicated to match the shape of arr1,
# (last dimension of `arr1` i.e., 3 does not match with the first dimension of `arr2` i.e., 2)
# therefore, broadcasting is unsuccessful and will flag an error
arr3 = arr1 + arr2
print("arr3: \n", arr3)
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) /var/folders/1t/g3ylw8h50cjdqmk5d6jh1qmm0000gn/T/ipykernel_7691/3649234492.py in <module> 2 # (last dimension of `arr1` i.e., 3 does not match with the first dimension of `arr2` i.e., 2) 3 # therefore, broadcasting is unsuccessful and will flag an error ----> 4 arr3 = arr1 + arr2 5 6 print("arr3: \n", arr3) ValueError: operands could not be broadcast together with shapes (2,3) (2,)
Example 2: Broadcast Error
# Consider adding a 2-D array (2x3) to a 1-D array with 2 values
arr1 = np.array([[1, 2], [3, 4], [5, 6], [7, 8]])
print("arr1:\n", arr1)
print("arr1.shape: ", arr1.shape)
arr2 = np.array([[4], [5], [6], [5]])
print("arr2:\n", arr2)
print("arr2.shape: ", arr2.shape)
arr1: [[1 2] [3 4] [5 6] [7 8]] arr1.shape: (4, 2) arr2: [[4] [5] [6] [5]] arr2.shape: (4, 1)
# Since arr2 cannot be replicated to match the shape of arr1,
# (last dimension of `arr1` i.e., 2 does not match with the first dimension of `arr2` i.e., 3)
# therefore, broadcasting is unsuccessful and will flag an error
try:
arr3 = arr1 + arr2
print("arr3: \n", arr3)
except ValueError as e:
print(e)
arr3: [[ 5 6] [ 8 9] [11 12] [12 13]]
Example 3: Broadcast Error
arr1 = np.array([[5, 3, 2],[3, 4, 5], [7, 1, 4]])
print("arr1:\n", arr1)
print("arr1.shape: ", arr1.shape)
arr2 = np.array([[100], [200]])
print("arr2:\n", arr2)
print("arr2.shape: ", arr2.shape)
# Since arr2 cannot be replicated to match the shape of arr1,
# (last dimension of `arr1` i.e., 3 does not match with the first dimension of `arr2` i.e., 2)
# therefore, broadcasting is unsuccessful and will flag an error
try:
arr3 = arr1 + arr2
print("arr3: \n", arr3)
except ValueError as e:
print(e)
shape
attribute (in-place operation)np.reshape()
method (shallow copy)np.resize()
method (deep copy)ndarray.transpose()
method (shallow copy)np.swapaxes()
method (shallow copy)ndarray.flatten()
method (deep copy)
np.shape
Attribute¶ndarray
is as simple as setting its shape
attribute. However, the array's size must remain the same.import numpy as np
arr1 = np.arange(24)
print("arr1:", arr1)
print("Dimensions:", arr1.ndim)
print("Shape:", arr1.shape)
print("Strides:", arr1.strides)
arr1: [ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23] Dimensions: 1 Shape: (24,) Strides: (8,)
#Changing the shape attribute (array size must remain same)
arr1.shape = (6, 4)
print("arr1: \n", arr1)
print("Dimensions:", arr1.ndim)
print("Shape:", arr1.shape)
print("Strides:", arr1.strides)
arr1: [[ 0 1 2 3] [ 4 5 6 7] [ 8 9 10 11] [12 13 14 15] [16 17 18 19] [20 21 22 23]] Dimensions: 2 Shape: (6, 4) Strides: (32, 8)
#Changing the shape attribute (array size must remain same)
arr1.shape = (2, 4, 3)
print("arr1: \n", arr1)
print("Dimensions:", arr1.ndim)
print("Shape:", arr1.shape)
print("Strides:", arr1.strides)
np.reshape()
Method¶np.reshape(arr, newshape)
np.reshape()
method takes the input array, then a tuple that defines the shape of the new array and returns a new array, which shares the same memory as the original array. You can 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.Example 1: Reshaping from 1-D numPy Arrays to 2-D numPy Arrays
arr1 = np.array([1, 2, 3, 4, 5, 6])
print("Original Array: ", arr1, "\nShape: ", arr1.shape)
Original Array: [1 2 3 4 5 6] Shape: (6,)
# Changing the dimension of array using reshape()
arr2 = np.reshape(arr1, (2, 3))
print("Reshaped Array: \n", arr2, "\nShape: ", arr2.shape)
Reshaped Array: [[1 2 3] [4 5 6]] Shape: (2, 3)
# make change in one of the arrays, the change is reflected in both
arr2[0][0] = 99
print("Original Array: ", arr1)
print("Reshaped Array: \n", arr2)
print("id(arr1): ", id(arr1))
print("id(arr2): ",id(arr2))
Example 2: Reshaping from 1-D numPy Arrays to 3-D numPy Arrays
arr1 = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
print("Original Array: ", arr1, "\nShape: ", arr1.shape)
arr2 = np.reshape(arr1, (2, 2, 3))
print("\nReshaped Array: \n", arr2, "\nShape: ", arr2.shape)
Example 3: Flattening Arrays. You can convert an array of an unknown dimension to a 1D array using np.reshape(-1)
arr1 = np.array([[1, 2, 3], [6, 7, 8], [4, 5, 6], [11, 14, 10]])
print("Original Array: \n", arr1, "\nShape: ", arr1.shape)
arr2 = np.reshape(arr1, (-1))
print("\nReshaped Array: \n", arr2, "\nShape: ", arr2.shape)
Example 4: Reshaping an array back to its original dimensions. If you applied the np.reshape()
method to an array and you want to get the original shape of the array back, you can call the reshape method on that array again.
arr1 = np.array([[1, 2, 3], [6, 7, 8], [4, 5, 6], [11, 14, 10]])
print("Original Array: \n", arr1, "\nShape: ", arr1.shape)
arr2 = np.reshape(arr1, (2, 6))
print("\nReshaped Array: \n", arr2, "\nShape: ", arr2.shape)
# covert the array into original shape again
arr3 = np.reshape(arr2, (4,3))
print("\nReshaped to Original Shape: \n", arr3, "\nShape: ", arr3.shape)
Example 5: You can reshape to any shape, the only requirement is that the total elements in both the arrays should be same
arr1 = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9])
arr2 = np.reshape(arr1, (3, 2))
arr2
np.resize()
Method¶np.resize(arr, newshape)
np.reshape()
method, the np.resize()
method also takes the input array and a tuple that defines the shape of the array, with one main difference and that is:newshape
argument mismatch with the size of arr
, it do not raise error. The new array is formed from the data in the old array, repeated if necessary to fill out the required number of elements.Example 1: Resizing from 1-D numPy Arrays to 2-D numPy Arrays. The new array doesnāt share the same memory with the original array. The data change in one array is not mapped to the other.
arr1 = np.array([1, 2, 3, 4, 5, 6])
print("Original Array: ", arr1, "\nShape: ", arr1.shape)
Original Array: [1 2 3 4 5 6] Shape: (6,)
# Changing the dimension of array using reshape()
arr2 = np.resize(arr1, (2, 3))
print("Resized Array: \n", arr2, "\nShape: ", arr2.shape)
Resized Array: [[1 2 3] [4 5 6]] Shape: (2, 3)
# make change in one of the arrays, the change is NOT reflected in both
arr2[0][0] = 99
print("Original Array: ", arr1)
print("Resized Array: \n", arr2)
print("id(arr1): ", id(arr1))
print("id(arr2): ",id(arr2))
Original Array: [1 2 3 4 5 6] Resized Array: [[99 2 3] [ 4 5 6]] id(arr1): 140539858671936 id(arr2): 140539859132704
Example 2: The np.resize()
method allows you to resize an array to a new array having larger size than the original array. In this scenario, it fills the remaining array with repeated copies of original array elements
arr1 = np.array([1, 2, 3, 4, 5, 6])
print("Original Array: ", arr1, "\nShape: ", arr1.shape)
arr2 = np.resize(arr1, (4,4))
print("\nResized Array: \n", arr2, "\nShape: ", arr2.shape)
Example 3: The np.resize()
method allows you to resize an array to a new array having smaller size than the original array.
arr1 = np.array([1, 2, 3, 4, 5, 6, 7, 8])
print("Original Array: ", arr1, "\nShape: ", arr1.shape)
arr2 = np.resize(arr1, (3, 2))
print("\nResized Array: \n", arr2, "\nShape: ", arr2.shape)
ndarray.transpose()
Method¶ndarray.transpose()
arr1 = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])
print("Original Array: \n", arr1, "\nShape: ", arr1.shape)
#Reshape array using transpose method
arr2 = arr1.transpose()
print("\nTransposed array: \n", arr2, "\nShape: ", arr2.shape)
## make change in one of the arrays, the change is reflected in both
arr2[1][1] = 99
print("\nOriginal Array: \n", arr1)
print("Transposed Array: \n", arr2)
np.swapaxes()
Method¶np.swapaxes()
method is used to interchange two axes of an array.np.swapaxes(arr, axis1, axis2)
- `arr`: Input array whose axes are to be swapped
- `axis1`: First axis
- `axis2`: Second axis
arr
is an ndarray, then a view of arr
is returned.Example 1: Swapping axes of a 2-D array
arr1 = np.arange(8).reshape(2,4)
print("Original Array: \n", arr1, "\nShape: ", arr1.shape)
#Reshape array using swapaxes() method
arr2 = np.swapaxes(arr1,0, 1)
print("\nNew array: \n", arr2, "\nShape: ", arr2.shape)
## make change in one of the arrays, the change is reflected in both
arr2[1][1] = 99
print("\nOriginal Array: \n", arr1)
print("\nNew Array: \n", arr2)
Example 2: Swapping axes of a 3-D array
arr1 = np.arange(8).reshape(2,2,2)
print("Original Array: \n", arr1, "\nShape: ", arr1.shape)
#Reshape array using swapaxes() method
arr2 = np.swapaxes(arr1,1, 2)
print("\nNew array: \n", arr2, "\nShape: ", arr2.shape)
ndarray.flatten()
Method¶ndarry.flatten()
method is used to flatten a Multi-Dimensional array/matrix to one dimension.ndarray.flatten(order= 'C')
arr1 = np.arange(12).reshape(4,3)
print("Original Array: \n", arr1, "\nDimensions: ", arr1.ndim)
Original Array: [[ 0 1 2] [ 3 4 5] [ 6 7 8] [ 9 10 11]] Dimensions: 2
# flatten the array in row-major order
arr2 = arr1.flatten(order = 'C')
print("\nFlattened array in row major order \n", arr2, "\nDimensions: ", arr2.ndim)
# flatten the array in column-major order
arr3 = arr1.flatten(order = 'F')
print("\nFlattened array in cloumn major order \n", arr3, "\nDimensions: ", arr3.ndim)
Flattened array in row major order [ 0 1 2 3 4 5 6 7 8 9 10 11] Dimensions: 1 Flattened array in cloumn major order [ 0 3 6 9 1 4 7 10 2 5 8 11] Dimensions: 1
np.sort()
Method¶np.sort()
method returns a sorted copy of an array.np.sort(arr1, axis=-1, kind=None)
- `arr` : Array to be sorted.
- `axis` : Axis along which we need array to be started. The default is -1, which sorts along the last axis. 0 stands for sorting along first axis. If metioned None, the array is flattened before sorting.
- `kind` : default is 'quicksort', others can be 'mergesort', 'heapsort'
import numpy as np
arr1 = np.random.randint(low = 1, high = 100, size = 5)
print("arr1 = ", arr1)
arr1 = [60 89 67 98 72]
arr2 = np.sort(arr1)
print("arr2 = ", arr2)
Example 1: Sorting a 2-D array with axis=None
, array is flattened before sorting
arr1 = np.random.randint(low = 1, high = 100, size = (3,3))
print("arr1: \n", arr1)
arr1: [[61 36 91] [73 97 9] [44 70 59]]
arr2 = np.sort(arr1, axis = None)
print ("\nSorting along axis=None: \n", arr2)
Sorting along axis=None: [ 9 36 44 59 61 70 73 91 97]
Example 2: Sorting a 2-D array with axis=0
, vertical axis, top to bottom
arr1 = np.random.randint(low = 1, high = 10, size = (3,3))
print("arr1 = \n", arr1)
arr1 = [[7 5 6] [8 3 6] [3 2 7]]
arr2 = np.sort(arr1, axis = 0)
print ("\nSorting along axis=0: \n", arr2)
Sorting along axis=0: [[3 2 6] [7 3 6] [8 5 7]]
Example 3: Sorting a 2-D array with axis=1
, horizontal axis, left to right
arr1 = np.random.randint(low = 1, high = 10, size = (3,3))
print("arr1 = \n", arr1)
arr1 = [[6 3 9] [3 5 4] [7 4 8]]
arr2 = np.sort(arr1, axis = 1)
print ("\nSorting along axis=1: \n", arr2)
Sorting along axis=1: [[3 6 9] [3 4 5] [4 7 8]]
ndarrays
is very similar to iterating over regular python arrays.Example 1: Iterating over 1-D numPy array
arr1 = np.arange(12)
arr1
for value in arr1:
print(value, end=' ')
Example 2: Iterating over 2-D numPy array is done w.r.t first axis, i.e., zero axis (column wise). In simple words in the first iteration you will get the first row, in second iteration you will get the 2nd row and so on...
arr1 = np.arange(12).reshape(4, 3)
print("arr1: \n",arr1)
for zero_axis in arr1:
print("Iteration:")
print(zero_axis)
Example 3: Iterating over 2-D numPy array
arr1 = np.arange(8).reshape(2, 4)
print("arr1: \n",arr1)
for zero_axis in arr1:
print("Iteration:")
print(zero_axis)
Example 4: Iterating over 3-D numPy array is done w.r.t first axis, i.e., zero axis (level wise). In simple words in the first iteration you will get the first row, in second iteration you will get the 2nd row and so on...
arr1 = np.arange(24).reshape(2, 3, 4)
print("arr1: \n",arr1)
for zero_axis in arr1:
print("Iteration:")
print(zero_axis)
Example 5: If you want to iterate on all elements in the ndarray
, simply iterate over the flat
attribute:
arr1 = np.arange(12).reshape(3, 4)
print("arr1: \n",arr1)
for i in arr1.flat:
print(i, end=' ')