Today I received a mail from a friend complaining that there are no new articles. While writing a new post on the blog had been running on my mind for the last few months, for lack of motivation, I was dilly dallying and resorted to the easy way out: procrastinating. VoilĂ , a shot in the arm and we are back in business
In this post, we will attempt to unveil some important aspects of NumPy. NumPy as we know today was released as NumPy 1.0 in 2006. As of today when we write this article, the version is 1.19.0. The Python versions supported by this release are 3.6-3.8. NumPy is the fundamental package for scientific computing in Python. At the centre of the NumPy package, a Python library, is the ndarray object or a n-dimensional arrays of homogeneous elements
We will be using Jupyter notebook for all the work in this article. The code is in blue font and output is in green font below the code. The version details are given below:
import sys
print("Python version:", sys.version)
import numpy as np
print("NumPy version:", np.__version__)
Python version: 3.8.3 (default, Jul 2 2020, 17:30:36) [MSC v.1916 64 bit (AMD64)]
NumPy version: 1.18.5
Let's start with creating a few NumPy arrays and then calling them immediately:
numpy_array1 = np.array([1, 2, 3, 4, 5])
numpy_array1
numpy_array2 = np.array([True, False, True, False, True], dtype = bool)
numpy_array2
array([ True, False, True, False, True])
numpy_array3
array([1.1, 2.2, 3.3, 4.4, 5.5])
numpy_array4 = np.array([1, 2, 3, 4, 5], dtype = np.uint8) ## dtype is Unsigned integer (0 to 255)
numpy_array4
array([1, 2, 3, 4, 5], dtype=uint8)
numpy_array5 = np.array(['NumPy',"is","the",'fundamental',"package",'for',"scientific",'computing'])
numpy_array5
array(['NumPy', 'is', 'the', 'fundamental', 'package', 'for',
'scientific', 'computing'], dtype='<U11')
We can also create NumPy arrays from list:
python_list = [6, 7, 8, 9, 10]
numpy_array6 = np.array(python_list)
numpy_array6
array([ 6, 7, 8, 9, 10])
Few more examples of NumPy arrays creation are shown below:
String = "1.1 2.2 3.3 4.4 5.5"
numpy_array7 = np.fromstring(String, dtype = np.double, sep = " ")
numpy_array7
array([1.1, 2.2, 3.3, 4.4, 5.5])
numpy_array8 = np.zeros((5,2), dtype = int) ## initializes with zeros
numpy_array8
array([[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0]])
numpy_array9 = np.eye(3, dtype = float) ## initializes with zeros but with ones along dialgonal
numpy_array9
[0., 1., 0.],
[0., 0., 1.]])
numpy_array10 = np.full((5, 4), 10) ## completes array with value for given shape
numpy_array10
array([[10, 10, 10, 10],
[10, 10, 10, 10],
[10, 10, 10, 10],
[10, 10, 10, 10],
[10, 10, 10, 10]])
To check the properties of arrays, we can use the following commands:
numpy_array11 = np.array([[ 1, 2, 3, 4, 5, 6, 7, 8],
[ 6, 7, 8, 9, 10, 11, 12, 13]])
numpy_array11
array([[ 1, 2, 3, 4, 5, 6, 7, 8],
[ 6, 7, 8, 9, 10, 11, 12, 13]])
numpy_array11.shape ## shape
(2, 8)
numpy_array11.size ## size
16
numpy_array11.ndim ## number of dimensions
2
numpy_array11.itemsize ## size of each item in bytes
4
numpy_array11.nbytes ##size in bytes of all elements
64
numpy_array11.dtype ## type of elements
dtype('int32')
len(numpy_array11) ## length of array
2
Operations on NumPy arrays are shown in the next few commands:
numpy_array_sum = numpy_array1 + numpy_array2 # Addition
numpy_array_sum
array([2, 2, 4, 4, 6])
numpy_array_difference = numpy_array1 - numpy_array2 # Subtraction
numpy_array_difference
array([0, 2, 2, 4, 4])
numpy_array_product = numpy_array1 * numpy_array2 # Multiplication
numpy_array_product
array([1, 0, 3, 0, 5])
numpy_array_quotient = numpy_array1 / numpy_array1 # Division
numpy_array_quotient
array([1., 1., 1., 1., 1.])
numpy_array_square_root = numpy_array1 ** 0.5 # square root
numpy_array_square_root
array([1. , 1.41421356, 1.73205081, 2. , 2.23606798])
numpy_array_raised_power = numpy_array1 ** 3 # Exponentiation
numpy_array_raised_power
array([ 1, 8, 27, 64, 125], dtype=int32)
numpy_array_sin = np.sin(numpy_array1) # array value treated as radians
numpy_array_sin
array([ 0.84147098, 0.90929743, 0.14112001, -0.7568025 , -0.95892427])
numpy_array_log = np.log(numpy_array1) # natural logarithm
numpy_array_log
array([0. , 0.69314718, 1.09861229, 1.38629436, 1.60943791])
Some of the constants that we may encounter in our line of work:
np.e
2.718281828459045
np.pi
3.141592653589793
np.inf
inf
np.Inf
inf
np.NINF
-inf
np.NAN
nan
np.NZERO
-0.0
np.PZERO
0.0
To compare two NumPy arrays, we can use the following commands:
np.equal(numpy_array2, numpy_array1) #Element wise comparison
array([ True, False, False, False, False])
numpy_array1 == numpy_array2 #Element wise comparison
array([ True, False, False, False, False])
np.array_equal(numpy_array1, numpy_array1) # Array Comparison
True
np.array_equal(numpy_array1, numpy_array2) # Array Comparison
False
Broadcasting in NumPy: For operations between arrays, a comparison is first made of their shapes element-wise. If the shapes are the same, then, no broadcasting is applied. But, if the sizes are not the same, then, for the operation to succeed, the size of trailing axes for both arrays in an operation must either be the same size or one of them must be one. Else, a ValueError: operands could not be broadcast together with shapes ... exception is thrown, indicating that the arrays have incompatible shapes and broadcasting could not be applied
numpy_array12 = np.arange(1,16).reshape(3,5)
numpy_array12
array([[ 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10],
[11, 12, 13, 14, 15]])
numpy_array12 + numpy_array12 # same shape so, no problem
array([[ 2, 4, 6, 8, 10],
[12, 14, 16, 18, 20],
[22, 24, 26, 28, 30]])
numpy_array13 = np.array([1])
numpy_array13
array([1])
numpy_array12 + numpy_array13 # broadcasting is valid as size of trailing axis of numpy_array13 is 1
array([[ 2, 3, 4, 5, 6],
[ 7, 8, 9, 10, 11],
[12, 13, 14, 15, 16]])
numpy_array14 = np.array([1, 2, 3, 4, 5])
numpy_array14
array([1, 2, 3, 4, 5])
numpy_array12 + numpy_array14 # broadcasting is valid as size of trailing axes of both arrays is 5 and is same
array([[ 2, 4, 6, 8, 10],
[ 7, 9, 11, 13, 15],
[12, 14, 16, 18, 20]])
numpy_array15 = np.array([1, 2])
numpy_array15
array([1, 2])
numpy_array12 + numpy_array15 # error will be thrown
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-32-ff4233b2f95d> in <module> ----> 1 numpy_array12 + numpy_array15 # error will be thrown ValueError: operands could not be broadcast together with shapes (3,5) (2,)
With this concept of Broadcasting in NumPy, we come to the end the first post on NumPy