Matrix Operations with Numpy

Base Python makes it tough to deal with matrices. Numpy is designed to deal with matrices!

import numpy as np

Looking at a sample matrix.

A sample matrix and accessing elements

matrix = np.array([[-2, 3, 1],
                   [0,  9, 2],
                   [3, -1, -1]])
print(matrix)
print(matrix.shape)
[[-2  3  1]
 [ 0  9  2]
 [ 3 -1 -1]]
(3, 3)

Each element of the matrix is specificed by a row and column (zero-indexed). We can access each element with slicing, which looks like this.

row    = 1
column = 0

print(matrix[row,column])
0

I can get entire rows or entire columns with the colon operator, which looks like this:

print(matrix[:,column])
[-2  0  3]
print(matrix[0:2,column]) # note that the slicing is NOT inclusive!
[-2  0]

Operations

Matrix Multiplication (np.matmul(), or the @ operator)

x = np.array([[1,0,0],
              [0,0,0],
              [0,0,0]])

y = np.random.rand(3,3)
print(y)
[[0.97923713 0.33310377 0.55035876]
 [0.23793526 0.68559354 0.97399356]
 [0.32381837 0.86097095 0.63983894]]
print(y @ x)
print(' ')
print(np.matmul(y,x))
[[0.97923713 0.         0.        ]
 [0.23793526 0.         0.        ]
 [0.32381837 0.         0.        ]]
 
[[0.97923713 0.         0.        ]
 [0.23793526 0.         0.        ]
 [0.32381837 0.         0.        ]]

Inverses

array = np.random.rand(3,3)
array_inverse = np.linalg.inv(array)
print(array)
print('')
print(array_inverse)
print('')
print(array @ array_inverse)
[[0.98999528 0.21515457 0.10983839]
 [0.02709303 0.19722765 0.55434032]
 [0.06301708 0.29939075 0.15645762]]

[[ 1.05862051  0.00609576 -0.76478413]
 [-0.24050117 -1.15941578  4.2767312 ]
 [ 0.03382804  2.21615434 -1.48423146]]

[[ 1.00000000e+00  8.72909715e-18 -8.19128027e-17]
 [ 1.55708672e-18  1.00000000e+00 -2.37544400e-17]
 [ 1.59851851e-17  1.24430881e-16  1.00000000e+00]]

Tranposing

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

print(x)
print('')
print(x.shape)
print('')
x_transpose = x.T # or np.tranpose()
print(x_transpose)
print('')
print(x_transpose.shape)
[[1 2 3]
 [4 5 6]]

(2, 3)

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

(3, 2)
x @ x_transpose
array([[14, 32],
       [32, 77]])
x @ x
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
/var/folders/8b/kdzzptnn501_n9y8q82g0c1w0000gn/T/ipykernel_7692/2542721134.py in <module>
----> 1 x @ x

ValueError: matmul: Input operand 1 has a mismatch in its core dimension 0, with gufunc signature (n?,k),(k,m?)->(n?,m?) (size 2 is different from 3)

Other useful functions that I use often:

  • np.zeros()

  • np.ones()

  • np.hstack() – stacks arrays columnwise

  • np.vstack() – stack arrays rowwise

  • np.save(), np.load() – saves and loads .npy files

  • np.genfromtxt(), np.loadtxt(), np.savetxt()

  • np.random.uniform()

  • np.random.normal()