Warm up

What will the following code spit out? (Don't just type it -- pencil and paper it).


In [ ]:
x = []
for i in range(1,11):
    if i > 2:
        x.append(i**2)
print(x[3])

How would you fix the following code so it does what you expect it to do?


In [ ]:
some_list = [1,2,3]
a_list_copy = some_list
some_list[1] = 273

Numpy Arrays

Python lists are powerful

  • Can store any python object
  • Can be expanded or contracted at will (append, insert,extend, remove, pop)

But would you want to cook with a swiss army knife?

Numpy arrays are the speciality knives of python programming

numpy arrays are:

  • Less flexible than lists:
    • Each array can only store one type of value
    • Arrays cannot be resized after they're made
  • But numpy arrays are fast and set up to do math
  • If you've ever done matlab programming, numpy arrays use the same syntax

Predict what the following code will print out (and be ready to explain each line)


In [ ]:
import numpy as np
an_array = np.array([1,2,3,4,5,6,7,8,9,10],dtype=np.int64)
print(an_array[3])

numpy arrays are an extension of python, not built in.

A quick return to lists:

Predict what this code will do.


In [ ]:
some_list = [1,2,3]
print(some_list)
print(some_list + 5)

Write a program to add 5 to every entry in the list [1,2,3]


In [ ]:

Predict what this code will do


In [ ]:
import numpy as np  
some_array = np.array([1,2,3])
some_array = some_array + 5
print(some_array)

You can do math on numpy arrays in an "element-wise" fashion.

numpy arrays are fast


In [ ]:
import numpy as np

a_list = list(range(100000))
an_array = np.array(range(100000),dtype=int)

In [ ]:
%timeit for i in range(100000):  a_list[i] + 5
%timeit an_array + 5

Can you explain what just happened?

  • for i in range(blah blah) is in pure python. This is convenient, but slow.
  • an_array + 5 actually runs the loop, but in compiled C. This is super fast.

moral: don't use loops when working with numpy arrays.

Predict what the following code will do


In [ ]:
import numpy as np
x = np.array([1,2,3])
y = np.array([4,5])

print(x + y)

In [ ]:
print(np.sin(x))

Summarize

How does math work with numpy arrays?

Predict what the following code will do


In [ ]:
an_array = np.array([[1,2],[3,4]],dtype=int)
print(an_array)

In [ ]:
an_array = np.zeros((2,2),dtype=float)
print(an_array)
an_array[0,0] = 1
an_array[0,1] = 2
an_array[1,0] = 3
an_array[1,1] = 4
print(an_array)

Summarize

How can you construct arrays?

Predict what the following code will do


In [ ]:
an_array = np.array([[1,2,3],[4,5,6],[7,8,9]],dtype=int)
print(an_array[-1])
print("")
print(an_array[0,0])
print("")
print(an_array[:,0].reshape(3,1))
print("")
print(an_array[:,:])

Summarize

How do you access elements inside multidimensional arrays?

Numpy arrays are real vectors and matrices

One major motivation for the authors who created numpy was to speed-up mathematical operations on vector, matrix, and tensor-like data structures.

Numpy vector math operations


In [ ]:
# Define two vector-like arrays
x = np.array([3,5])
y = np.array([4,6])

print("Element wise sum:" ,          x + y )         # Addition
print("Element wise difference:",    x - y )         # Substraction
print("Element wise product:",       x * y)          # Product
print("Element wise division:",      x / y)          # division
print("Dot product:",                np.dot(x, y))   # Dot product

Numpy matrix math operations


In [ ]:
# Define a matrix
M = np.array([
    [5, 3],
    [2, 7]
])

print("Matrix transpose:\n",          M.T)                # Transpose
print("Vector-matrix dot product",    np.dot(M, x))       # Dot product
print("Matrix determinant:",          np.linalg.det(M))   # Determinant
print("Matrix inverse:\n",            np.linalg.inv(M))   # inverse

Solve a system of equations

Solve a system of equations using numpy.linalg.solve function.

Example: $$ 3 x + 2y - z = 1 \\ 2 x - 5y + 4z = -2 \\ -x + \frac{1}{2} y - z = 0 $$

Written in matrix form: $$ A \vec{x} = \vec{b} $$

$$ \left[ \begin{array}{ccc} 3 & 2 & -1 \\ 2 & -5 & 4 \\ -1 & \frac{1}{2} & -1 \\ \end{array} \right] % \left[ \begin{array}{c} x \\ y \\ z \end{array} \right] = \left[ \begin{array}{c} 1 \\ -2 \\ 0 \end{array} \right] $$

</small>


In [ ]:
A = np.array([
    [ 3,   2, -1],
    [ 2,  -2,  4],
    [-1, 0.5, -1]
])
b = np.array([1, -2, 0])

print("x :",  np.linalg.solve(A, b))

Numpy to eigensystems

Easily diagonalize a matrix using numpy.linalg.eig function.

Example: $$ M \vec{v} = \lambda \vec{v} $$ </small>


In [ ]:
M = np.array([
    [5, 3],
    [2, 7]
])

λs, eigvec = np.linalg.eig(M)

print("λ 1:",                λs[0])
print("Eigen vector 1:",     eigvec[0])
print("\n")
print("λ 2:",                λs[1])
print("Eigen vector 2:",     eigvec[1])

Summary

  1. To get a numpy array, put import numpy as np at the top of your code
  2. Arrays are fast, but less flexible than list
  3. You can do element-wise math on each array
  4. You create N-dimensional arrays and slice by some_array[i,j,k]
  5. Arrays are vectors and matrices that allow linear algebra