{ "metadata": { "name": "" }, "nbformat": 3, "nbformat_minor": 0, "worksheets": [ { "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "This is part of [**Python for Geosciences**](https://github.com/koldunovn/python_for_geosciences) notes." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "================" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- a powerful N-dimensional array object\n", "- sophisticated (broadcasting) functions\n", "- tools for integrating C/C++ and Fortran code\n", "- useful linear algebra, Fourier transform, and random number capabilities\n" ] }, { "cell_type": "code", "collapsed": false, "input": [ "set_printoptions(precision=3 , suppress= True) # this is just to make the output look better" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 5 }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Load data" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "I am going to use some real data as an example of array manipulations. This will be the AO index downloaded by wget through a system call (you have to be on Linux of course):" ] }, { "cell_type": "code", "collapsed": false, "input": [ "!wget www.cpc.ncep.noaa.gov/products/precip/CWlink/daily_ao_index/monthly.ao.index.b50.current.ascii" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This is how data in the file look like (we again use system call for *head* command):" ] }, { "cell_type": "code", "collapsed": false, "input": [ "!head monthly.ao.index.b50.current.ascii" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ " 1950 1 -0.60310E-01\r\n", " 1950 2 0.62681E+00\r\n", " 1950 3 -0.81275E-02\r\n", " 1950 4 0.55510E+00\r\n", " 1950 5 0.71577E-01\r\n", " 1950 6 0.53857E+00\r\n", " 1950 7 -0.80248E+00\r\n", " 1950 8 -0.85101E+00\r\n", " 1950 9 0.35797E+00\r\n", " 1950 10 -0.37890E+00\r\n" ] } ], "prompt_number": 6 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Load data in to a variable:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "ao = loadtxt('monthly.ao.index.b50.current.ascii')" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 7 }, { "cell_type": "code", "collapsed": false, "input": [ "ao" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 8, "text": [ "array([[ 1950. , 1. , -0.06 ],\n", " [ 1950. , 2. , 0.627],\n", " [ 1950. , 3. , -0.008],\n", " ..., \n", " [ 2013. , 7. , -0.011],\n", " [ 2013. , 8. , 0.154],\n", " [ 2013. , 9. , -0.461]])" ] } ], "prompt_number": 8 }, { "cell_type": "code", "collapsed": false, "input": [ "ao.shape" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 9, "text": [ "(765, 3)" ] } ], "prompt_number": 9 }, { "cell_type": "markdown", "metadata": {}, "source": [ "So it's a *row-major* order. Matlab and Fortran use *column-major* order for arrays." ] }, { "cell_type": "code", "collapsed": false, "input": [ "type(ao)" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 10, "text": [ "numpy.ndarray" ] } ], "prompt_number": 10 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Numpy arrays are statically typed, which allow faster operations" ] }, { "cell_type": "code", "collapsed": false, "input": [ "ao.dtype" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 11, "text": [ "dtype('float64')" ] } ], "prompt_number": 11 }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can't assign value of different type to element of the numpy array:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "ao[0,0] = 'Year'" ], "language": "python", "metadata": {}, "outputs": [ { "ename": "ValueError", "evalue": "could not convert string to float: Year", "output_type": "pyerr", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[1;31mValueError\u001b[0m Traceback (most recent call last)", "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mao\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m]\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;34m'Year'\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[1;31mValueError\u001b[0m: could not convert string to float: Year" ] } ], "prompt_number": 12 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Slicing works similarly to Matlab:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "ao[0:5,:]" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 13, "text": [ "array([[ 1950. , 1. , -0.06 ],\n", " [ 1950. , 2. , 0.627],\n", " [ 1950. , 3. , -0.008],\n", " [ 1950. , 4. , 0.555],\n", " [ 1950. , 5. , 0.072]])" ] } ], "prompt_number": 13 }, { "cell_type": "markdown", "metadata": {}, "source": [ "One can look at the data. This is done by matplotlib module and you have to start IPython with *--pylab inline* option to make it work:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "plot(ao[:,2])" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 14, "text": [ "[]" ] }, { "metadata": {}, "output_type": "display_data", "png": "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\n", "text": [ "" ] } ], "prompt_number": 14 }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Index slicing" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In general it is similar to Matlab" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "First 12 elements of **second** column (months). Remember that indexing starts with 0:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "ao[0:12,1]" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 15, "text": [ "array([ 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11.,\n", " 12.])" ] } ], "prompt_number": 15 }, { "cell_type": "markdown", "metadata": {}, "source": [ "First raw:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "ao[0,:]" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 17, "text": [ "array([ 1950. , 1. , -0.06])" ] } ], "prompt_number": 17 }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can create mask, selecting all raws where values in second raw (months) equals 10 (October):" ] }, { "cell_type": "code", "collapsed": false, "input": [ "mask = (ao[:,1]==10)" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 18 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here we apply this mask and show only first 5 rowd of the array:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "ao[mask][:5,:]" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 19, "text": [ "array([[ 1950. , 10. , -0.379],\n", " [ 1951. , 10. , -0.213],\n", " [ 1952. , 10. , -0.437],\n", " [ 1953. , 10. , -0.194],\n", " [ 1954. , 10. , 0.513]])" ] } ], "prompt_number": 19 }, { "cell_type": "markdown", "metadata": {}, "source": [ "You don't have to create separate variable for mask, but apply it directly. Here instead of first five rows I show five last rows:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "ao[ao[:,1]==10][-5:,:]" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 20, "text": [ "array([[ 2008. , 10. , 1.676],\n", " [ 2009. , 10. , -1.54 ],\n", " [ 2010. , 10. , -0.467],\n", " [ 2011. , 10. , 0.8 ],\n", " [ 2012. , 10. , -1.514]])" ] } ], "prompt_number": 20 }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can combine conditions. In this case we select October-December data (only first 10 elements are shown):" ] }, { "cell_type": "code", "collapsed": false, "input": [ "ao[(ao[:,1]>=10)&(ao[:,1]<=12)][0:10,:]" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 21, "text": [ "array([[ 1950. , 10. , -0.379],\n", " [ 1950. , 11. , -0.515],\n", " [ 1950. , 12. , -1.928],\n", " [ 1951. , 10. , -0.213],\n", " [ 1951. , 11. , -0.069],\n", " [ 1951. , 12. , 1.987],\n", " [ 1952. , 10. , -0.437],\n", " [ 1952. , 11. , -1.891],\n", " [ 1952. , 12. , -1.827],\n", " [ 1953. , 10. , -0.194]])" ] } ], "prompt_number": 21 }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Basic operations" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Create example array from first 12 values of second column and perform some basic operations:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "months = ao[0:12,1]\n", "months" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 22, "text": [ "array([ 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11.,\n", " 12.])" ] } ], "prompt_number": 22 }, { "cell_type": "code", "collapsed": false, "input": [ "months+10" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 23, "text": [ "array([ 11., 12., 13., 14., 15., 16., 17., 18., 19., 20., 21.,\n", " 22.])" ] } ], "prompt_number": 23 }, { "cell_type": "code", "collapsed": false, "input": [ "months*20" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 24, "text": [ "array([ 20., 40., 60., 80., 100., 120., 140., 160., 180.,\n", " 200., 220., 240.])" ] } ], "prompt_number": 24 }, { "cell_type": "code", "collapsed": false, "input": [ "months*months" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 25, "text": [ "array([ 1., 4., 9., 16., 25., 36., 49., 64., 81.,\n", " 100., 121., 144.])" ] } ], "prompt_number": 25 }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Basic statistics" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Create *ao_values* that will contain onlu data values:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "ao_values = ao[:,2]" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 26 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Simple statistics:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "ao_values.min()" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 27, "text": [ "-4.2656999999999998" ] } ], "prompt_number": 27 }, { "cell_type": "code", "collapsed": false, "input": [ "ao_values.max()" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 28, "text": [ "3.4952999999999999" ] } ], "prompt_number": 28 }, { "cell_type": "code", "collapsed": false, "input": [ "ao_values.mean()" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 29, "text": [ "-0.13462109949019607" ] } ], "prompt_number": 29 }, { "cell_type": "code", "collapsed": false, "input": [ "ao_values.std()" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 30, "text": [ "1.0054168027600721" ] } ], "prompt_number": 30 }, { "cell_type": "code", "collapsed": false, "input": [ "ao_values.sum()" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 31, "text": [ "-102.98514111" ] } ], "prompt_number": 31 }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can also use *sum* function:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "sum(ao_values)" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 32, "text": [ "-102.98514111" ] } ], "prompt_number": 32 }, { "cell_type": "markdown", "metadata": {}, "source": [ "One can make operations on the subsets:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "mean(ao[ao[:,1]==1,2]) # January monthly mean" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 33, "text": [ "-0.40406150000000002" ] } ], "prompt_number": 33 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Result will be the same if we use method on our selected data:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "ao[ao[:,1]==1,2].mean()" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 34, "text": [ "-0.40406150000000002" ] } ], "prompt_number": 34 }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Saving data" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can save your data as a text file" ] }, { "cell_type": "code", "collapsed": false, "input": [ "savetxt('ao_only_values.csv',ao[:, 2], fmt='%.4f')" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 36 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Head of resulting file:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "!head ao_only_values.csv" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "-0.0603\r\n", "0.6268\r\n", "-0.0081\r\n", "0.5551\r\n", "0.0716\r\n", "0.5386\r\n", "-0.8025\r\n", "-0.8510\r\n", "0.3580\r\n", "-0.3789\r\n" ] } ], "prompt_number": 37 }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can also save it as binary:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "f=open('ao_only_values.bin', 'w')\n", "ao[:,2].tofile(f)\n", "f.close()" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 38 } ], "metadata": {} } ] }