{ "cells": [ { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Introduction to programming for Geoscientists through Python\n", "### [Gerard Gorman](http://www.imperial.ac.uk/people/g.gorman), [Nicolas Barral](http://www.imperial.ac.uk/people/n.barral)\n", "\n", "# Lecture 5: Array computing and curve plotting" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "Learning objectives: \n", "\n", "* Learn how to compute using numpy arrays, *i.e.* vectorise code.\n", "* Learn how to generate 2D graphs." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Vectors and arrays\n", "\n", "You have known **vectors** since high school mathematics, *e.g.*, point $(x,y)$ in the plane, point $(x,y,z)$ in space. In general, we can describe a vector $v$ as an $n$-tuple of numbers: $v=(v_0,\\ldots,v_{n-1})$. One way to store vectors in Python is by using *lists*: $v_i$ is stored as *v[i]*." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "**Arrays** are a generalization of vectors where we can have multiple indices: $A_{i,j}$, $A_{i,j,k}$. In Python code this is represented as a nested list (see previous lecture), accessed as *A[i][j]*, *A[i][j][k]*.\n", "\n", "Example: table of numbers, one index for the row, one for the column\n", "$$\n", "\\left\\lbrack\\begin{array}{cccc}\n", "0 & 12 & -1 & 5q\n", "-1 & -1 & -1 & 0\\cr\n", "11 & 5 & 5 & -2\n", "\\end{array}\\right\\rbrack\n", "\\hspace{1cm}\n", "A =\n", "\\left\\lbrack\\begin{array}{ccc}\n", "A_{0,0} & \\cdots & A_{0,n-1}\\cr\n", "\\vdots & \\ddots & \\vdots\\cr\n", "A_{m-1,0} & \\cdots & A_{m-1,n-1}\n", "\\end{array}\\right\\rbrack\n", "$$\n", "The number of indices in an array is the *rank* or *number of dimensions*. Using these terms, a vector can be described as a one-dimensional array, or rank 1 array." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "In practice, we use [Numerical Python (*NumPy*)](http://www.numpy.org/) arrays instead of lists to represent mathematical arrays because it is **much** faster for large arrays.\n", "\n", "Let's consider an example where we store $(x,y)$ points along a curve in Python lists and numpy arrays:" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": true, "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "# Sample function\n", "def f(x):\n", " return x**3\n", "\n", "# Generate n points in [0,1]\n", "n = 5\n", "dx = 1.0/(n-1) # x spacing\n", "\n", "xlist = [i*dx for i in range(n)] # Python lists\n", "ylist = [f(x) for x in xlist]\n", "\n", "# Turn these Python lists into Numerical Python (NumPy) arrays:\n", "from numpy import *\n", "x2 = array(xlist)\n", "y2 = array(ylist)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Instead of first making lists with $x$ and $y = f (x)$ data, and then turning lists into arrays, we can make NumPy arrays\n", "directly:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": true, "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "n = 5 # number of points\n", "x2 = linspace(0, 1, n) # generates n points between 0 and 1\n", "y2 = zeros(n) # n zeros (float data type by default)\n", "for i in range(n): \n", " y2[i] = f(x2[i])" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "List comprehensions create lists, not arrays, but we can do:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": true, "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "y2 = array([f(xi) for xi in x2]) # list -> array" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### When and where to use NumPy arrays\n", "\n", "* Python lists can hold any sequence of any Python objects, however, NumPy arrays can only hold objects of the same type.\n", "* Arrays are most efficient when the elements are of basic number types (*float*, *int*, *complex*).\n", "* In that case, arrays are stored efficiently in the computer's memory and we can compute very efficiently with the array elements.\n", "* Mathematical operations on whole arrays can be done without loops in Python. For example," ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": true, "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "x = linspace(0, 2, 10001)\n", "y = zeros(10001)\n", "for i in range(len(x)):\n", " y[i] = sin(x[i])" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "can be coded as" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": true, "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "y = sin(x)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "In the latter case the loop over all elements is now performed in a very efficient C function.\n", "\n", "Operations on whole arrays, instead of using Python *for*-loops, is called vectorization and is a very **convenient**, **efficient** and therefore important programming technique to master." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Let's consider a simple vectorisation example: a loop to compute $x$ coordinates (*x2*) and $y=f(x)$ coordinates (*y2*) along a function curve:" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": true, "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "x2 = linspace(0, 1, n)\n", "y2 = zeros(n)\n", "for i in range(n):\n", " y2[i] = f(x2[i])" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "This computation can be replaced by:" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": true, "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "x2 = linspace(0, 1, n)\n", "y2 = f(x2)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "The advantage of this approach is:\n", "\n", "* There is no need to allocate space for y2 (via the NumPy *zeros* function).\n", "* There is no need for a loop.\n", "* It is *much* faster." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## How vectorised functions work\n", "Consider the function" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": true, "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "def f(x):\n", " return x**3" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "$f(x)$ is intended for a number $x$, *i.e.* a *scalar*. So what happens when we call *f(x2)*, where *x2* is an NumPy array? **The function simply evaluates $x^3$ for an array x**. NumPy supports arithmetic operations on arrays, which correspond to the equivalent operations on each element, *e.g.*:" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "array([ 0.00000000e+00, 6.66600003e-05, 1.33306669e-04, ...,\n", " 2.45252956e-01, 2.45252960e-01, 2.45252961e-01])" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x**3 # x[i]**3 forr all i\n", "cos(x) # cos(x[i]) for all i\n", "x**3 + x*cos(x) # x[i]**3 + x[i]*cos(x[i]) for all i\n", "x/3*exp(-x*0.5) # x[i]/3*exp(-x[i]*0.5) for all i " ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "In each of these cases a highly optimised C function is actually called to evaluate the expression. In this example, the *cos* function called for an *array* is imported from *numpy* rather than from the *math* module which only acts on scalars.\n", "\n", "Notes:\n", "\n", "* Functions that can operate on arrays are called **vectorized functions**.\n", "* Vectorization is the process of turning a non-vectorized expression/algorithm into a vectorized expression/algorithm.\n", "* Mathematical functions in Python automatically work for both scalar and array (vector) arguments, *i.e.* no vectorization is needed by the programmer.\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Watch out for references Vs. copies of arrays!\n", "Consider this code:" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "42.0\n" ] } ], "source": [ "a=x\n", "a[-1] = 42\n", "print(x[-1])" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Notice what happened here - we changed a value in *a* but the corresponding value in *x* was also changed! This is because *a* refers to the same array as *x*. If you really want a seperate copy of *x* then we have to make an explicit copy:" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "collapsed": true, "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "a = x.copy()" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Exercise 5.1: Fill lists and arrays with function values\n", "A function with many applications in science is defined as:

\n", "$h(x) = \\frac{1}{\\sqrt{2\\pi}}\\exp(-0.5x^2)$

\n", "\n", "* Fill two lists *xlist* and *hlist* with *x* and *h(x)* values for uniformly spaced *x* coordinates in [−4, 4]. You may adapt the first example in the lecture 4 notes.\n", "\n", "* Fill two arrays *x* and *y* with *x* and *h(x)* values, respectively, where *h(x)* is defined above. Let the *x* values be uniformly spaced in [−4, 4]. Use list comprehensions to create the *x* and *y* arrays.\n", "\n", "* Vectorize the code by creating the *x* values using the *linspace* function and by evaluating *h(x)* for an array argument." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true, "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Exercise 5.2: Apply a function to a vector\n", "Given a vector $v = (2, 3, −1)$ and a function $f(x) = x^3 + xe^x + 1$, apply $f$ to each element in $v$. Then calculate $f(v)$ as $v^3 + ve^v + 1$ using vector computing rules. Show that the two results are equal." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true, "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Exercise 5.3: Simulate by hand a vectorized expression\n", "Suppose *x* and *t* are two arrays of the same length, and given the vectorized expression,\n", "\n", "```python\n", "y = cos(sin(x)) + exp(1/t)\n", "```\n", "\n", "assuming *x* holds two elements, 0 and 2, and *t* holds the elements 1 and 1.5, calculate by hand (using a calculator) the *y* array.\n", "\n", "Write a program that mimics the series of computations you did by hand (use explicit loops, but at the end you can use NumPy functionality to check the results)." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true, "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Generalised array indexing\n", "We can select a slice of an array using *a[start:stop:inc]*, where the slice *start:stop:inc* implies a set of indices starting from *start*, up to *stop* in increments of *inc*. In fact, any integer list or array can be used to indicate a set of indices:" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[ 1. 2. 3. 4. 5. 6. 7. 8.]\n" ] } ], "source": [ "a = linspace(1, 8, 8)\n", "print(a)" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[ 1. 10. 3. 4. 5. 6. 10. 10.]\n" ] } ], "source": [ "a[[1,6,7]] = 10 # i.e. set the elements with indicies 1,6, and 7 in the list to 10.\n", "print(a)" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[ 1. 10. -2. 4. 5. -2. 10. 10.]\n" ] } ], "source": [ "a[range(2,8,3)] = -2 # same as a[2:8:3] = -2\n", "print(a)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Even boolean expressions can also be used to select part of an array(!)" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[-2. -2.]\n" ] } ], "source": [ "print(a[a < 0]) # pick out all negative elements" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[ 1. 10. 10. 4. 5. 10. 10. 10.]\n" ] } ], "source": [ "a[a < 0] = a.max() # if a[i]<0, set a[i]=10\n", "print(a)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Exercise 5.4: Demonstrate array slicing\n", "Create an array *w* with values 0, 0.1, 0.2, ..., 3. Write out *w[:]*, *w[:-2]*, *w[::5]*, *w[2:-2:6]*. Convince yourself in each case that you understand which elements of the array are printed." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true, "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Plotting curves - the basics\n", "First of all, a little house keeping. There are quite a few ways of plotting graphs etc. in Python. Currently the best way is using [PyLab](http://wiki.scipy.org/PyLab). If you are someone who likes the details then please go to the [PyLab](http://wiki.scipy.org/PyLab) website and read. Secondly, because we are doing this within IPython NoteBook, and we do not want additional windows popping up all over the place, we execute this next line:" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Populating the interactive namespace from numpy and matplotlib\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "/home/nbuser/anaconda3_431/lib/python3.6/site-packages/IPython/core/magics/pylab.py:160: UserWarning: pylab import has clobbered these variables: ['f']\n", "`%matplotlib` prevents importing * from pylab and numpy\n", " \"\\n`%matplotlib` prevents importing * from pylab and numpy\"\n" ] } ], "source": [ "%pylab inline" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Now, onwards and upwards...\n", "\n", "A curve $y = f(x)$ stored in the 1D NumPy arrays *x* and *y* can easily be plotted:" ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "data": { "image/png": "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\nSinlQ/4/iboA1k3RIWkAAAAASUVORK5CYII=\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "t = linspace(0, 3, 51)\n", "y = t**2*exp(-t**2)\n", "plot(t, y)\n", "show()" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Plots also should have **labels** on the axis, a **title**, and sometimes a specific extent of the axis (perhaps you wish to easily compare two graphs side-by-side):" ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "def f(t):\n", " return t**2*exp(-t**2)\n", "\n", "t = linspace(0, 3, 51) # Generates 51 points between 0 and 3\n", "y = f(t)\n", "plot(t, y)\n", "\n", "xlabel('t')\n", "ylabel('y')\n", "legend(('t^2*exp(-t^2)',))\n", "axis([0, 3, -0.05, 0.6]) # specify the extent of the axes [tmin, tmax, ymin, ymax]\n", "\n", "title('My second PyLab graph')\n", "show()" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Exercise 5.5: Plot a formula\n", "* Make a plot of the function $y(t) = v_0t − 0.5gt^2$ for $v_0 = 10$, $g = 9.81$, and $t \\in [0, 2v_0/g]$. The label on the *x* axis should be 'time (s)' and the label on the *y* axis should be 'height (m)'.\n", "* Extend the program such that the minimum and maximum *x* and *y* values are computed, and use the extreme values to specify the extent of the *x* and *y* axes. Add some space above the heighest curve." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true, "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Exercise 5.6: Plot another formula\n", "The function

\n", "$f(x, t) = \\exp(-(x - 3t)^2)\\sin(3\\pi(x - t))$\n", "

\n", "describes, for a fixed value of *t*, a wave localized in space. Make a program that visualizes this function as a function of *x* on the interval [−4, 4] when *t* = 0." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true, "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Multiple curves in one plot\n", "We can also plot several curves in one plot:" ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "def f1(t):\n", " return t**2*exp(-t**2)\n", "\n", "def f2(t):\n", " return t**2*f1(t)\n", "\n", "t = linspace(0, 3, 51)\n", "y1 = f1(t)\n", "y2 = f2(t)\n", "\n", "# Matlab-style syntax:\n", "plots = plot(t, y1, t, y2)\n", "legend(plots, ('t^4*exp(-t^2)', 't^4*exp(-t^2)'), loc='best')\n", "xlabel('t')\n", "ylabel('y')\n", "title('Plotting two curves in the same plot')\n", "show()" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "When plotting multiple curves in the same plot, PyLab usually does a good job in making sure that the different lines actually look different. However, sometimes you need to take action yourself (*e.g.* if you need to print your graph out in black&white). To do this we can add an extra argument to the plot command where we specify what we want - *e.g.* \"r-\" means a *red line*, while \"bo\" means *blue circles*:" ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "image/png": "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\nrkJggg==\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "plot(t, y1, 'r-', t, y2, 'bo')\n", "show()" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "For further examples check out the [PyLab website](http://scipy.org/PyLab)." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Exercise 5.7: Plot a formula for several parameters\n", " - Make a program in which you define a set of $v_0$ values and plot the corresponding curves $y(t) = v_0t − 0.5gt^2$ in the same figure (set $g = 9.81$). Let $t \\in [0, 2v_0/g$] for each curve, which implies that you need a different vector of $t$ coordinates for each curve.\n", " - Make a similar program where the values of $v_0$ are given by the user through an iPython widget as a series of numbers separated by a comma." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true, "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## 2D arrays\n", "When we have a table of numbers,\n", "\n", "$$\n", "\\left\\lbrack\\begin{array}{cccc}\n", "0 & 12 & -1 & 5\\cr\n", "-1 & -1 & -1 & 0\\cr\n", "11 & 5 & 5 & -2\n", "\\end{array}\\right\\rbrack\n", "$$\n", "\n", "(*i.e.* a *matrix*) it is natural to use a two-dimensional array $A_{i,j}$ with one index for the rows and one for the columns:\n", "\n", "$$\n", "A = \n", "\\left\\lbrack\\begin{array}{ccc}\n", "A_{0,0} & \\cdots & A_{0,n-1}\\cr\n", "\\vdots & \\ddots & \\vdots\\cr\n", "A_{m-1,0} & \\cdots & A_{m-1,n-1}\n", "\\end{array}\\right\\rbrack\n", "$$\n", "\n", "Let's recreate this array using NumPy:" ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[ 0. 12. -1. 5.]\n", " [ -1. -1. -1. 0.]\n", " [ 11. 5. 5. -2.]]\n" ] } ], "source": [ "A = zeros((3,4))\n", "A[0,0] = 0\n", "A[1,0] = -1\n", "A[2,0] = 11\n", "\n", "A[0,1] = 12\n", "A[1,1] = -1\n", "A[2,1] = 5\n", "\n", "A[0,2] = -1\n", "A[1,2] = -1\n", "A[2,2] = 5\n", "\n", "# we can also use the same syntax that we used for nested lists\n", "\n", "A[0][3] = 5\n", "A[1][3] = 0\n", "A[2][3] = -2\n", "\n", "print(A)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Next let's convert a nested list from a previous example into a 2D array:" ] }, { "cell_type": "code", "execution_count": 23, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[0, 32.0], [10, 50.0], [20, 68.0], [30, 86.0], [40, 104.0], [50, 122.0], [60, 140.0], [70, 158.0], [80, 176.0], [90, 194.0], [100, 212.0]]\n" ] } ], "source": [ "Cdegrees = range(0, 101, 10)\n", "Fdegrees = [9./5*C + 32 for C in Cdegrees]\n", "table = [[C, F] for C, F in zip(Cdegrees, Fdegrees)]\n", "print(table)" ] }, { "cell_type": "code", "execution_count": 24, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[ 0. 32.]\n", " [ 10. 50.]\n", " [ 20. 68.]\n", " [ 30. 86.]\n", " [ 40. 104.]\n", " [ 50. 122.]\n", " [ 60. 140.]\n", " [ 70. 158.]\n", " [ 80. 176.]\n", " [ 90. 194.]\n", " [ 100. 212.]]\n" ] } ], "source": [ "# Convert this into a NumPy array:\n", "table2 = array(table)\n", "print(table2)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "To see the number of elements in each dimension:" ] }, { "cell_type": "code", "execution_count": 25, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(11, 2)\n" ] } ], "source": [ "print(table2.shape)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "*i.e.* 11 rows and 2 columns." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Let's write a loop over all array elements of A:" ] }, { "cell_type": "code", "execution_count": 26, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "table2[0,0] = 0\n", "table2[0,1] = 32\n", "table2[1,0] = 10\n", "table2[1,1] = 50\n", "table2[2,0] = 20\n", "table2[2,1] = 68\n", "table2[3,0] = 30\n", "table2[3,1] = 86\n", "table2[4,0] = 40\n", "table2[4,1] = 104\n", "table2[5,0] = 50\n", "table2[5,1] = 122\n", "table2[6,0] = 60\n", "table2[6,1] = 140\n", "table2[7,0] = 70\n", "table2[7,1] = 158\n", "table2[8,0] = 80\n", "table2[8,1] = 176\n", "table2[9,0] = 90\n", "table2[9,1] = 194\n", "table2[10,0] = 100\n", "table2[10,1] = 212\n" ] } ], "source": [ "for i in range(table2.shape[0]):\n", " for j in range(table2.shape[1]):\n", " print('table2[%d,%d] = %g' % (i, j, table2[i,j]))" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Alternatively:" ] }, { "cell_type": "code", "execution_count": 27, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "index (0, 0) has value 0\n", "index (0, 1) has value 32\n", "index (1, 0) has value 10\n", "index (1, 1) has value 50\n", "index (2, 0) has value 20\n", "index (2, 1) has value 68\n", "index (3, 0) has value 30\n", "index (3, 1) has value 86\n", "index (4, 0) has value 40\n", "index (4, 1) has value 104\n", "index (5, 0) has value 50\n", "index (5, 1) has value 122\n", "index (6, 0) has value 60\n", "index (6, 1) has value 140\n", "index (7, 0) has value 70\n", "index (7, 1) has value 158\n", "index (8, 0) has value 80\n", "index (8, 1) has value 176\n", "index (9, 0) has value 90\n", "index (9, 1) has value 194\n", "index (10, 0) has value 100\n", "index (10, 1) has value 212\n" ] } ], "source": [ "for index_tuple, value in ndenumerate(table2):\n", " print('index %s has value %g' % (index_tuple, table2[index_tuple]))" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "We can also extract slices from multi-dimensional arrays as before. For example, extract the second column:" ] }, { "cell_type": "code", "execution_count": 28, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[ 32. 50. 68. 86. 104. 122. 140. 158. 176. 194. 212.]\n" ] } ], "source": [ "print(table2[:, 1]) # 2nd column (index 1)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Play with this more complicated example:" ] }, { "cell_type": "code", "execution_count": 29, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[ 1. 2. 3. 4. 5. 6.]\n", " [ 7. 8. 9. 10. 11. 12.]\n", " [ 13. 14. 15. 16. 17. 18.]\n", " [ 19. 20. 21. 22. 23. 24.]\n", " [ 25. 26. 27. 28. 29. 30.]]\n" ] } ], "source": [ "t = linspace(1, 30, 30).reshape(5, 6)\n", "print(t)" ] }, { "cell_type": "code", "execution_count": 30, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[ 9. 10. 11. 12.]\n", " [ 21. 22. 23. 24.]]\n" ] } ], "source": [ "print(t[1:-1:2, 2:])" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Exercise 5.8: Implement matrix-vector multiplication\n", "A matrix $\\mathbf{A}$ and a vector $\\mathbf{b}$, represented in Python as a 2D array and a 1D array respectively, are given by:\n", "\n", "$$\n", "\\mathbf{A} = \\left\\lbrack\\begin{array}{ccc}\n", "0 & 12 & -1\\cr\n", "-1 & -1 & -1\\cr\n", "11 & 5 & 5\n", "\\end{array}\\right\\rbrack\n", "$$\n", "\n", "$$\n", "\\mathbf{b} = \\left\\lbrack\\begin{array}{c}\n", "-2\\cr\n", "1\\cr\n", "7\n", "\\end{array}\\right\\rbrack\n", "$$\n", "\n", "Multiplying a matrix by a vector results in another vector $\\mathbf{c}$, whose components are defined by the general rule\n", "\n", "$$\\mathbf{c}_i = \\sum_j\\mathbf{A}_{i,j}\\mathbf{b}_j$$\n", "\n", "Define $\\mathbf{A}$ and $\\mathbf{b}$ as NumPy arrays, and multiply them together using the above rule." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true, "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Exercise 5.9: Plot meteorological data\n", "The file data/precipitation.csv contains monthly precipitation data for South-East England between 1916 and 2016 provided by the [Met Office](https://www.metoffice.gov.uk/hadobs/hadukp/data/download.html). Each row represents a year, and each column a month.\n", "To open the data file, use the command below:\n", "\n", "```python\n", "import numpy as np\n", "data = np.loadtxt(fname='data/precipitation.csv', delimiter=',')\n", "```\n", "\n", " - Open the data file, and print its content. Observe that it is a multi-dimensional Numpy array. Print its shape. How many years are represented ?\n", " \n", " - Write a function that converts a length in mm into a length in inches. Use this function to convert the precipitation data into inches in a vectorized way.\n", " \n", " - With a `for` loop, print (in a formatted way) for each month, the year where the monthly precipitation was the highest. A line like:
\n", "`The maximal precipitation for January is 181.9 mm/month and was reached in 2014.`
\n", "is expected.
\n", "Hint: you should use the [max](https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.amax.html) and [argmax](https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.argmax.html) functions provided by Numpy.\n", "\n", " - Plot the [average](https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.mean.html), [maximal](https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.amax.html) and [minimal](https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.amin.html) monthly precipitation with respect to the year. Don't forget to decorate the plot properly (add a plot title, legends and axis labels).\n", " \n", " - Plot the same quantities, but only for the last twenty years.\n", " \n", " - Plot the same quantities, but only for years ending in 6." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true, "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [] } ], "metadata": { "celltoolbar": "Slideshow", "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.5.2" } }, "nbformat": 4, "nbformat_minor": 1 }