Skip to content
Marcel Stampfer edited this page Nov 2, 2015 · 16 revisions

Python tutorial

This tutorial loosely follows the topics covered in the Octave tutorial in week 2 of the course

wThe modules needed to run this tutorial are imported below

import numpy as np
import scipy.io
import scipy.misc
import matplotlib.pyplot as plt

Elementary arithmetic operations

Python is capable of working like a calculator with some caveats.
5+6
11
3-2
1
5*8
40
Beware: integer division rounds the result down! You can implicitly convert to a float by adding a '.'
1/2
0
1./2 
0.5
Exponents use the '**' operator
2**6
64

Logical operations

Every object has a boolean value returned from bool(). The following elements are false:
  • None
  • False
  • 0
  • Empty collections: “”, (), [], {}
1 and 0 # AND
0
1 or 0 # OR
1
1 != 0 # XOR
True
bool([]) and True # False
False
a='foo'
b='bar'
bool(a) != bool(b)
False
b=None
bool(a) != bool(b)
True

Python variables and types

Displaying variables

Variables are displayed on the console by typing the variable name
b=3
b
3
from math import pi
b=pi
b
3.141592653589793

floating point numbers are formatted in two ways:

The 'old' way (pre-python 2.7):

print '%1.4f'%b
3.1416
The 'new' way (python 2.7+):
print '{:1.5}'.format(b)
3.1416

Numpy basics

Vectors and matrices

a=np.array([[1,2],[3,4],[5,6]]) # 3x2 numpy matrix
a
array([[1, 2],
       [3, 4],
       [5, 6]])
v=[1,2,3]   # ordinary python list
v
[1, 2, 3]
v=np.array([1,2,3]) # numpy array
v
array([1, 2, 3])
Use np.arange(start, stop, increment) to generate a sequence of floats in a numpy array
v=np.arange(1,2,0.1)
v
array([ 1. ,  1.1,  1.2,  1.3,  1.4,  1.5,  1.6,  1.7,  1.8,  1.9])
Use tolist() to convert a numpy array to a python list
v.tolist()
[1.0,
 1.1,
 1.2000000000000002,
 1.3000000000000003,
 1.4000000000000004,
 1.5000000000000004,
 1.6000000000000005,
 1.7000000000000006,
 1.8000000000000007,
 1.9000000000000008]
The range() built-in function generates integer sequences in a list
v=range(1,6)
v
[1, 2, 3, 4, 5]
numpy's linspace function generates a non-integer sequence with a specific number of elements
v=np.linspace(1,2,11)
v
array([ 1. ,  1.1,  1.2,  1.3,  1.4,  1.5,  1.6,  1.7,  1.8,  1.9,  2. ])

Comprehensions

list comprehensions

List comprehensions allow you to create iterative code without using a loop
v=[1,2,3]
[e**2 for e in v]
[1, 4, 9]
[e**2 for e in v if e%2 !=0]
[1, 9]
[e**2 if e%2 != 0 else -1 for e in v]
[1, -1, 9]

dictionary comprehensions

Dictionary comprehensions allow to generate dictionaries without a loop
d = {'a':1, 'b':2, 'c':3}   
{v: k for k, v in d.items()}   # swap keys and values
{1: 'a', 2: 'b', 3: 'c'}
{1: 'a', 2: 'b', 3: 'c'}

set comprehension

Set comrehensions generate sets in a similar way
{x**2 for x in [1, 1, 2]}
set([1, 4])
{1, 4}

Special matrix functions

ones=np.ones((3,2))
ones
array([[ 1.,  1.],
       [ 1.,  1.],
       [ 1.,  1.]])
3*ones
array([[ 3.,  3.],
       [ 3.,  3.],
       [ 3.,  3.]])
np.zeros((3,2))
array([[ 0.,  0.],
       [ 0.,  0.],
       [ 0.,  0.]])
Generate an array of uniform random numbers
np.random.rand(3,2)
array([[ 0.62274829,  0.09702351],
       [ 0.63787983,  0.7836852 ],
       [ 0.2725037 ,  0.05886131]])
Generate an array of normal random numbers
np.random.randn(3,2)
array([[ 0.91457171, -2.09292019],
       [-0.66121188,  1.47599627],
       [ 0.5300655 , -0.7618794 ]])
id=np.eye(3)
id
array([[ 1.,  0.,  0.],
       [ 0.,  1.,  0.],
       [ 0.,  0.,  1.]])
3*id
array([[ 3.,  0.,  0.],
       [ 0.,  3.,  0.],
       [ 0.,  0.,  3.]])

Moving data around

shape and size of a matrix

a=np.random.rand(3,2)
a
array([[ 0.71577494,  0.51011023],
       [ 0.60835921,  0.34374784],
       [ 0.92554381,  0.85963944]])
a.shape
(3, 2)
a.size
6

Loading files in python

Reading the contents of a simple text file
file=open('ex6/emailSample1.txt', 'r')
file_contents=file.read()
file_contents
"> Anyone knows how much it costs to host a web portal ?\n>\nWell, it depends on how many visitors you're expecting.\nThis can be anywhere from less than 10 bucks a month to a couple of $100. \nYou should checkout http://www.rackspace.com/ or perhaps Amazon EC2 \nif youre running something big..\n\nTo unsubscribe yourself from this mailing list, send an email to:\[email protected]\n\n"
Loading image files
%pylab inline    # this line works in ipython only
data = scipy.misc.imread('ex7/bird_small.png')
plt.imshow(data)
Populating the interactive namespace from numpy and matplotlib





<matplotlib.image.AxesImage at 0x104fa6690>

png

Loading the contents of a csv file
data = np.loadtxt('ex0.csv', delimiter=',')
data
array([[  6.1101,  17.592 ],
       [  5.5277,   9.1302],
       [  8.5186,  13.662 ],
       [  7.0032,  11.854 ],
       [  5.8598,   6.8233]])
Loading a Matlab formatted file
data = scipy.io.loadmat('ex3/ex3data1.mat')
data
{'X': array([[ 0.,  0.,  0., ...,  0.,  0.,  0.],
        [ 0.,  0.,  0., ...,  0.,  0.,  0.],
        [ 0.,  0.,  0., ...,  0.,  0.,  0.],
        ..., 
        [ 0.,  0.,  0., ...,  0.,  0.,  0.],
        [ 0.,  0.,  0., ...,  0.,  0.,  0.],
        [ 0.,  0.,  0., ...,  0.,  0.,  0.]]),
 '__globals__': [],
 '__header__': 'MATLAB 5.0 MAT-file, Platform: GLNXA64, Created on: Sun Oct 16 13:09:09 2011',
 '__version__': '1.0',
 'y': array([[10],
        [10],
        [10],
        ..., 
        [ 9],
        [ 9],
        [ 9]], dtype=uint8)}

Manipulating matrices

Indexing and Slicing

a[start:end] - items start through end-1

a[start:] - items start through the rest of the array

a[:end] - items from the beginning through end-1

a[:] - a copy of the whole array

There is also the step value, which can be used with any of the above:

a[start:end:step] - start through not past end, by step

x = np.arange(10)
x
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
x[:]
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
x[1:]
array([1, 2, 3, 4, 5, 6, 7, 8, 9])
x[:5]
array([0, 1, 2, 3, 4])
x[2]
2
x[1:7:2]
array([1, 3, 5])

Negative indices

a[-1] - last item in the array
a[-2:] - last two items in the array
a[:-2] - everything except the last two items
x[:-2]
array([0, 1, 2, 3, 4, 5, 6, 7])
2d matrices are accessed in the row, column order
arr2d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
arr2d
array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])
arr2d[2]
array([7, 8, 9])
arr2d[0]
array([1, 2, 3])
arr2d[0,1]
2

Boolean indexing

Index selection can be done by filtering elements with boolean values

mat = np.array(['The', 'quick', 'brown', 'fox', 'jumped', 'over', 'the', 'lazy', 'dog']).reshape((3,3))
mat
array([['The', 'quick', 'brown'],
       ['fox', 'jumped', 'over'],
       ['the', 'lazy', 'dog']], 
      dtype='|S6')
rand = np.random.randn(3,3)>0
rand
array([[False, False,  True],
       [ True,  True,  True],
       [ True, False, False]], dtype=bool)
mat[rand]
array(['brown', 'fox', 'jumped', 'over', 'the'], 
      dtype='|S6')

Flattening

Reshaping from a higher dimensional to one dimensional order is called flattening

arr = np.arange(9).reshape((3,3))
arr
array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])
The flatten() function returns a copy of the array
arr.flatten()
array([0, 1, 2, 3, 4, 5, 6, 7, 8])
flattening can be done columnwise
arr.flatten(1)
array([0, 3, 6, 1, 4, 7, 2, 5, 8])
the ravel() function doesn't return a copy of the underlying data
arr.ravel()
array([0, 3, 6, 1, 4, 7, 2, 5, 8])

Vector assignments

Python doesn't create copies of underlying data on assignment statements

arr = np.arange(10)
arr
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
create a reference to some elements in the array and reassign them
slice=arr[4:8]
slice
array([4, 5, 6, 7])
slice[:]=-5
slice
array([-5, -5, -5, -5])
slice[1]=50
slice
array([-5, 50, -5, -5])
arr
array([ 0,  1,  2,  3, -5, 50, -5, -5,  8,  9])
now create a copy of the array explicitly and reassign
arr_copy=arr.copy()
arr_copy
array([ 0,  1,  2,  3, -5, 50, -5, -5,  8,  9])
arr_copy[4:8]=20
arr_copy
array([ 0,  1,  2,  3, 20, 20, 20, 20,  8,  9])
The original array is unchanged
arr
array([ 0,  1,  2,  3, -5, 50, -5, -5,  8,  9])

Horizontal and vertical concatenation

There are two ways to concatenate

mat = np.array(['The', 'quick', 'brown', 'fox'])
mat2 = np.array(['jumped', 'over', 'the', 'lazy'])
Method 1: Use stacking
 np.hstack((mat,mat2))
array(['The', 'quick', 'brown', 'fox', 'jumped', 'over', 'the', 'lazy'], 
      dtype='|S6')
 np.vstack((mat,mat2))
array([['The', 'quick', 'brown', 'fox'],
       ['jumped', 'over', 'the', 'lazy']], 
      dtype='|S6')
 np.column_stack((mat,mat2))
array([['The', 'jumped'],
       ['quick', 'over'],
       ['brown', 'the'],
       ['fox', 'lazy']], 
      dtype='|S6')
Method 2: Use the concatenate() function applied to an axis
arr = np.arange(12).reshape((3, 4))
arr
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
np.concatenate((arr,arr), axis=1)
array([[ 0,  1,  2,  3,  0,  1,  2,  3],
       [ 4,  5,  6,  7,  4,  5,  6,  7],
       [ 8,  9, 10, 11,  8,  9, 10, 11]])
np.concatenate((arr,arr), axis=0)
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
arr = np.arange(5)
np.concatenate((arr,arr), axis=0)
array([0, 1, 2, 3, 4, 0, 1, 2, 3, 4])

Matrix multiplication

x=np.array([[1,2,3], [4,5,6], [7,8,9]])
y=np.array([[1,2,3], [4,5,6], [7,8,9]])
np.dot(x,y)
array([[ 30,  36,  42],
       [ 66,  81,  96],
       [102, 126, 150]])
Matrix multiplication is done using the dot() function
x.dot(y)
array([[ 30,  36,  42],
       [ 66,  81,  96],
       [102, 126, 150]])
Element-wise multiplication using the '*' operator
x*y
array([[ 1,  4,  9],
       [16, 25, 36],
       [49, 64, 81]])
Element-wise squaring
x**2
array([ 0,  1,  4,  9, 16, 25, 36, 49, 64, 81])
Element-wise reciprical
1./x
array([[ 1.        ,  0.5       ,  0.33333333],
       [ 0.25      ,  0.2       ,  0.16666667],
       [ 0.14285714,  0.125     ,  0.11111111]])
Element-wise logarithms/exponents
np.log(x)
array([[ 0.        ,  0.69314718,  1.09861229],
       [ 1.38629436,  1.60943791,  1.79175947],
       [ 1.94591015,  2.07944154,  2.19722458]])
np.exp(x)
array([[  2.71828183e+00,   7.38905610e+00,   2.00855369e+01],
       [  5.45981500e+01,   1.48413159e+02,   4.03428793e+02],
       [  1.09663316e+03,   2.98095799e+03,   8.10308393e+03]])
Element-wise addition
1+x
array([[ 2,  3,  4],
       [ 5,  6,  7],
       [ 8,  9, 10]])

Transpose of a matrix

x.T
array([[1, 4, 7],
       [2, 5, 8],
       [3, 6, 9]])

Maximum and minimum of matrix values

np.max(x)
9
np.min(x)
1

Sum and product of all elements

np.sum(x)
45
np.sum(x,axis=0)
array([12, 15, 18])
np.sum(x,axis=1)
array([ 6, 15, 24])
np.sum(x)
45
np.product(x)
362880
np.product(x,axis=0)
array([ 28,  80, 162])
np.product(x,axis=1)
array([  6, 120, 504])

Inverse and pseudo-inverse of a matrix

x=2*np.eye(3)
np.linalg.inv(x)
array([[ 0.5,  0. ,  0. ],
       [ 0. ,  0.5,  0. ],
       [ 0. ,  0. ,  0.5]])
np.linalg.pinv(x)
array([[ 0.5,  0. ,  0. ],
       [ 0. ,  0.5,  0. ],
       [ 0. ,  0. ,  0.5]])

##Plotting data ###Plotting generated data

plt.plot(np.arange(10))
[<matplotlib.lines.Line2D at 0x10dd05f50>]

png

Line color, labels, title and legend

Saving a graph

Subplots

Axis scaling

Creating/clearing figures

Control statements

For loops

li = ['a', 'b', 'e']
for e in li:
    print e
a
b
e
d = enumerate(li)
for k,v in d:
    print k,v
0 a
1 b
2 e

While loops

n = ''
while n.strip() != 'hello':
    n = raw_input("Please enter 'hello':")
Please enter 'hello':goodbye
Please enter 'hello':hello

break statement

while True:
    n = raw_input("Please enter 'hello':")
    if n.strip() == 'hello':
        break
Please enter 'hello':bye
Please enter 'hello':hello

if-elif-else statement

x = int(raw_input("Please enter an integer: "))

if x < 0:
    x = 0
    print 'Negative changed to zero'
elif x == 0:
    print 'Zero'
elif x == 1:
    print 'Single'
else:
    print 'More'
Please enter an integer: 42
More

Functions

PYTHONPATH environment variable

Vectorization

Vectorized implementation

Unvectorized implementation

Clone this wiki locally