#!/usr/bin/env python # coding: utf-8 # # Numpy # # Numpy is python's library for numerical linear algebra, and provides a wealth of functionality for working with vectors, matrices, and tensors. # # Our first step is to **import** the package (note the "import as" shortcut): # In[1]: import numpy as np # Arrays are the standard data containers in numpy, and can have any number of dimensions. # # Let's create a one dimensional array: # In[2]: a = np.array([1, 2, 3]) a print(type(a)) print(a.shape) # Accessing/modifying array elements: # In[3]: print(a[0], a[1], a[2]) a[0] = 5 # Change an element of the array a # Two dimensional arrays: # In[4]: b = np.array([[1,2,3],[4,5,6]]) b,b.shape print(b[0, 0], b[0, 1], b[1, 0]) print(b[0][0], b[0][1], b[1][0]) # Some functions for creating arrays: # In[5]: a = np.zeros((2,2)) # Create an array of zeros print(a) b = np.ones((2,2)) # Create an array of ones print(b) c = np.full((2,2), 7.0) # Create a constant array (can also be done with the ones function) print(c) d = np.eye(2) # Create a 2x2 identity matrix print(d) e = np.random.random((3,3)) print(e) f = np.arange(2, 3, 0.1) print(f) g = np.linspace(1., 4., 6) print(g) # ### Sidenote - getting **help** on python objects: # # For getting help e.g. on the Numpy **linspace** function you can do one of the following: # # ```python # ?np.linspace # ``` # # or # # ```python # help(np.linspace) # ``` # In[6]: # ## Array indexing # # In[7]: X = np.array([[1,2,3,4], [5,6,7,8], [9,10,11,12]]) X # We'll think of this matrix as containing three feature vectors: each row of the matrix is a vector of features, and each column is the set of values that a given feature has in the data. # # To access the vector of features of the first example in the dataset: # In[8]: row = X[0] # the first row of X row, row.shape # To access a column of the matrix (a single feature): # In[9]: col = X[:, 0] col, col.shape # There are multiple ways of accessing sub-arrays. The first uses **slices**, similarly to python lists: # In[10]: submatrix = X[1:3, 1:4] submatrix, submatrix.shape # And here's my favorite way of indexing an array, using an integer array: # # In[11]: X[ [0, 2] ] # extract a given set of rows # In[12]: X[:, [0,2]] # extract a given set of columns # ## Operations on arrays # # You can multiply an array by a scalar: # # In[13]: x = np.array([1,1]) x * 2 # Add arrays: # In[14]: x + np.array([1,0]) # ### Dot products # In[15]: X = np.array([[1,2,3,4], [5,6,7,8], [9,10,11,12]]) # Let's construct a weight vector for a linear classifier: # # In[16]: w = np.array([1,-1, 2, -1]) w # We can easily compute the dot/inner product of a row of # X with the weight vector: # In[17]: np.dot(X[0], w) # Or you can do it for the whole matrix at once: # In[18]: np.dot(X, w) # This can also be done using methods: # In[19]: X.dot(w) # and can also be achieved using # In[20]: np.inner(X, w) # ## Other linear algebra operations # # Numpy has many other useful things it can do for you when it comes to vectors and matrices. # It's very easy to find the inverse of a matrix: # In[21]: Z = np.array([[2,1,1],[1,2,2],[2,3,4]]) np.linalg.inv(Z) # And we can easily verify that this is correct: # In[22]: np.dot(Z, np.linalg.inv(Z))==np.eye(3) # You can compute some useful statistics over your matrix such the mean and standard deviation: # In[23]: X = np.array([[1,2,3,4], [5,6,7,8], [9,10,11,12]]) X.mean(), X.mean(axis=0), X.mean(axis=1) # In[24]: X.std(), X.std(axis=0), X.std(axis=1) # There are lots of other things you can do with numpy: # In[25]: x = np.array( [1,2,3,4] ) y = np.array( [5,6,7,8] ) np.vstack([x,y]) np.hstack([x,y]) # ### Avoid loops when you can # # Consider the following piece of code: # In[26]: x = np.array([[1,2,3], [4,5,6], [7,8,9], [10, 11, 12]]) v = np.array([1, 0, 1]) y = np.empty_like(x) # Create an empty matrix with the same shape as x # Add the vector v to each row of the matrix x with an explicit loop for i in range(4): y[i, :] = x[i, :] + v y # As we know, loops are slow in python. There is a much more efficient way of doing this: # In[27]: x = np.array([[1,2,3], [4,5,6], [7,8,9], [10, 11, 12]]) v = np.array([1, 0, 1]) y = x + v y # This is called **broadcasting**. # ### Numpy documentation # # These were some of the basics that are relevant to our course. You can find more details in the [Numpy user manual](https://docs.scipy.org/doc/numpy/user/) and the detailed [reference guide](https://docs.scipy.org/doc/numpy/reference). # The following is a good resource for learning how to [vectorize](http://www.labri.fr/perso/nrougier/from-python-to-numpy/) Python code using Numpy for obtaining good performance. # Some aspects of these tutorial were inspired by this [tutorial](http://cs231n.github.io/python-numpy-tutorial/).