<jupyter_start><jupyter_text>Guide to Numpy Operations> short tutorial on standard Numpy linear algebra operations- toc: true - badges: true- comments: true- categories: [Numpy, Python, LinearAlgebra, Math]- image: images/numpylogo.png  A Short Guide to Numpy Array operations. Introducing Numpy Arrays:Numpy is a python library used to create, modify and interact with Arrays. It is a very vast and powerful library which is very essential for data analysis tasks. The Numpy library basic routines are very simple and easy to learn. Numpy is also known for scientific computation since it can handle large amount of data in the form of arrays. Numpy is mostly written in C which makes it run time fast and execute operations faster. It is very useful for Mathematics since it offers a vast collection of mathematical functions and random number generators. In this notebook, I try to demonstrate some standard numpy operations essential for operating on matrices. Below are the five operations that I am going to demonstrate:- np.matmul- np.linalg.solve- np.column_stack(tup)- np.bmat- np.logThe demonstrating includes the syntax of using these operations and how to pass arguments for these functions. It also demonstrates in what special cases do we get errors using these operations and also how to solve fix the erorrs efficiently. Let's begin by importing Numpy and listing out the functions covered in this notebook.<jupyter_code>import numpy as np
# List of functions explained 
function1 = np.matmul 
function2 = np.linalg.solve
function3 = np.column_stack
function4 = np.bmat
function5 = np.emath<jupyter_output><empty_output><jupyter_text>Function 1 - np.matmulThe np.matmul operator is a matrix multiplication operator used to multiply arrays.The @ is short form for using this operator.The function has the following syntax:np.matmul(a,b)-- where a,b are arrays that are to be multiplied.<jupyter_code># Example 1 - working (change this)
arr1 = [[15, 24], 
        [33, 4.]]

arr2 = [[5, 16, 37], 
        [18, 9, 20]]

mult=np.matmul(arr1,arr2)
print(mult)<jupyter_output>[[ 507.  456. 1035.]
 [ 237.  564. 1301.]]<jupyter_text>Explanation: The matmul operator takes two 2d arrays i.e. arr1 and arr2 abd multiplied by  matrix multiplication. Inorder for arrays to be able to perform matrix multiplication the 2nd dimension of arr1 should be equal to first dimension of arr2. Here they satisfy the condition and the output is generated. If the dimensions of two arrays do not satisfy the property we get a traceback error msg telling us there is a mismatch in dimensions.<jupyter_code># Example 2 - working
np.matmul([2j, 3j], [2j, 3j])<jupyter_output><empty_output><jupyter_text>The vector vector gives us scalar inner product. Given two vector arrays the np.matmul operation does dot product or also called as scalar product. The 0j in the output is the complex part of the output since there are no complex numbers involved we get zero complex part in our output<jupyter_code># Example 3 - breaking (to illustrate when it breaks)
arr1 = [[15,24,32], 
        [3, 4.,12]]

arr2 = [[5, 6, 7], 
        [8, 9, 10]]

np.matmul(arr1,arr2)<jupyter_output><empty_output><jupyter_text>It breaks because matrix multiplication takes place only when the second dimension of the first array is equal to first dimension of the second array. This function is used to multiply arrays, for dot product of two vectors and multiplication of 3d arrays etc.  Function 2 - np.linalg.solveThis operator is used to solve linear equations and give out the value of unknowns from the system of linear equations. For example ax = b be a system of linear equations and the above function solves the equation for x. a, b are matrices formed from the system of linear equations.In mathematical terms, a is the coefficient matrix and x is the vector containing unknowns and b is the right hand side values of the system of equations.The function has the following syntax:np.linalg.solve(a,b) where a,b are arrays coefficient matrix , dependant variable matrix.<jupyter_code># Example 1 - working
a = [[5,6],
     [7,8]]
b = [12,16]
x = np.linalg.solve(a,b)
print(x)<jupyter_output>[0. 2.]<jupyter_text>Here we found the solution for the system of linear equations where a is coefficient matrix and b is the solution matrix.the system of linear equations are of the form:5*m + 6*n = 127*m + 8*n = 16and the matrix a is made from the coefficients of the equationsthe output gives a vector x of two elements that are the solutions of m and n respectively.  Example 2 - working<jupyter_code>a = [[2,3,4],[8,4,2],[5,3,4]]
b = [12,16,18]
x = np.linalg.solve(a,b)
print(x)<jupyter_output>[ 2.  -1.6  3.2]<jupyter_text>The above example is based on three linear equations in three variables.the np.linalg.solve all kinds of systems of linear equations.<jupyter_code># Example 3 - breaking (to illustrate when it breaks)
a = [[1,2,3],[4,5,6],[7,8,9]]
b = [12,16,18]
x = np.linalg.solve(a,b)<jupyter_output><empty_output><jupyter_text>It breaks down above because solving of linear equations has some conditions. If the matrix is singular the output does not give any solution. singular matrix is one that is not invertible. This means that the system of equations you are trying to solve does not have a unique solution.    This function proves very useful when we need to solve n number of linear equations in n variables and gives the solution. There are a lot of uses for the function Mathematically since it reduced the load of solving linear equations by row reduction process, which is very tedious and most times do not provide accurate solution.  Function 3 - np.column_stacknp.column_stack is used to stack two 1-D arrays into a 2D array of column wise.It is used in the following format np.column_stack(tuple). The parameter is given as tuple type. The 1D array are entered as tuples. The function has the following syntax:np.column_stack(tuple)<jupyter_code># Example 1 - working
a = np.array((4,5,6))
b = np.array((12,14,17))
c = np.column_stack((a,b))
print(c)<jupyter_output>[[ 4 12]
 [ 5 14]
 [ 6 17]]<jupyter_text>The two arrays a and b are stacked side by side / column wise and the output array is a 2D array containing one column(a) and the other column(b)<jupyter_code># Example 2 - working
a = np.array((3,34,53,72,65,81))
b = np.array((2,5,43,76,83,92))
c = np.column_stack((a,b))
print(c)<jupyter_output>[[ 3  2]
 [34  5]
 [53 43]
 [72 76]
 [65 83]
 [81 92]]<jupyter_text>The above example stacks two given arrays in the form of tuples and stacks them side by side.<jupyter_code># Example 3 - breaking (to illustrate when it breaks)
a = np.array((1,2,3,4))
b = np.array((12,13,14))
c = np.column_stack((a,b))
print(c)<jupyter_output><empty_output><jupyter_text>The function breaks down because one of the array is longer in size than the other. The concatenation or stacking takes place only when both the arrays to be stacked has same size. The function is very useful when we need to stack two list .Similar to appending but here we are appending columns. The function can be used to add the column to pre-existing ones.  Function 4 - np.bmatIt builds a matrix object from a string, nested sequence or an array.The function has the following syntax:np.bmat(object,ldict,gdict)where ldict and gdict are dictionaries and they are optional parameters and object is either string or array-like.<jupyter_code># Example 1 - working
A = np.mat('1 1; 1 1')
B = np.mat('2 2; 2 2')
C = np.mat('3 4; 5 6')
D = np.mat('7 8; 9 0')
np.bmat([[A, B], [C, D]])<jupyter_output><empty_output><jupyter_text>The above example takes four arrays A,B,C,D and builds up a matrix by stacking A and B, C and D column wise and then stacking the arrays row wise one top of the another.<jupyter_code># Example 2 - working
A = np.mat('12 13; 14 15')
B = np.mat('23 28; 24 22')
C = np.mat('34 45; 57 69')
D = np.mat('7 8; 9 0')
np.bmat([[B, A], [D, C]])<jupyter_output><empty_output><jupyter_text>The above example takes the arrays A,B,C,D and builds the matrix by stacking them as per the order of the parameters given in the paranthesis of the function.<jupyter_code># Example 3 - breaking (to illustrate when it breaks)
A = np.mat('12 13; 14 15 18')
B = np.mat('23 28; 24 22')
C = np.mat('34 45; 57 69')
D = np.mat('7 8; 9 0 12')
np.bmat([[B, A], [D, C]])<jupyter_output><empty_output><jupyter_text>It breaks because there the sizes of the rows are different so they cannot be stacked. The sizes of the rows or columns that are getting stacked must be of the same size inorder to stack them and build the matrix.To fix this we need to remove the extra rows in the arrays or add NaN element to others to make the rows of same size. The function is useful when we have some groups of arrays and we want to stack them into a matrix to perform operations and gain insights from that build matrix.  Function 5 - np.logThe function is used to calculate log values of the elements of the arrayThe sytax for the function is: np.log(x)-- x is array-like<jupyter_code># Example 1 - working
np.log([1, np.e, np.e**2])<jupyter_output><empty_output><jupyter_text>In the above example the function took the input parameters and calculated the individual log values of the elements and gives the output.<jupyter_code># Example 2 - working
np.log([1, 0, np.e])<jupyter_output>/tmp/ipykernel_36/1939558749.py:2: RuntimeWarning: divide by zero encountered in log
  np.log([1,0, np.e])<jupyter_text>The above example demonstrates that the np.log function even takes 0 and gives the -inf as the output. It gives a warning because the function detects a zero division because of log (0) computation.<jupyter_code># Example 3 - breaking (to illustrate when it breaks)
np.log([1, np.e, a])<jupyter_output>/tmp/ipykernel_36/1874325113.py:2: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray.
  np.log([1, np.e, a])
{'fraction_non_alphanumeric': 0.08116689819408612, 'fraction_numerical': 0.03353840047628498, 'mean_word_length': 4.621305075292805, 'pattern_counts': {'":': 0, '<': 58, '<?xml version=': 0, '>': 59, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '16', 'dir': 'jupyter-structured-clean-dedup', 'id': '587705', 'license': 'Apache-2.0', 'n_tokens_mistral': 3221, 'n_tokens_neox': 2947, 'n_words': 1441, 'path': '_notebooks/2021-10-03-Guide-to-Numpy-Operations.ipynb', 'repo_name': 'sandeshkatakam/My-Machine_learning-Blog', 'size': '10078'}