{ "metadata": { "name": "" }, "nbformat": 3, "nbformat_minor": 0, "worksheets": [ { "cells": [ { "cell_type": "heading", "level": 1, "metadata": {}, "source": [ "Modularization and Documentation" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now that we've covered some of the basic syntax and libraries in Python we can start to tackle our data analysis problem.\n", "We are interested in understanding the relationship between the weather and the number of mosquitos so that we can plan mosquito control measures.\n", "Since we want to apply these mosquito control measures at a number of different sites we need to understand how the relationship varies across sites.\n", "Remember that we have a series of CSV files with each file containing the data for a single location." ] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Objectives" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* Write code for people, not computers\n", "* Break a program into chunks\n", "* Write and use functions in Python\n", "* Write useful documentation" ] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Starting small" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "When approaching computational tasks like this one it is typically best to start small,\n", "check each piece of code as you go,\n", "and make incremental changes.\n", "This helps avoid marathon debugging sessions\n", "because it's much easier to debug one small piece of the code at a time than to write 100 lines of code and\n", "then try to figure out all of the different bugs in it.\n", "\n", "Let's start by reading in the data from a single file and conducting a simple regression analysis on it.\n", "In fact, I would actually start by just importing the data and making sure that everything is coming in OK." ] }, { "cell_type": "code", "collapsed": false, "input": [ "import pandas as pd\n", "\n", "d = pd.read_csv('A2_mosquito_data.csv')\n", "print d" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ " year temperature rainfall mosquitos\n", "0 1960 82 200 180\n", "1 1961 70 227 194\n", "2 1962 89 231 207\n", "3 1963 74 114 121\n", "4 1964 78 147 140\n", "5 1965 85 151 148\n", "6 1966 86 172 162\n", "7 1967 75 106 112\n", "8 1968 70 276 230\n", "9 1969 86 165 162\n", "10 1970 83 222 198\n", "11 1971 78 297 247\n", "12 1972 87 288 248\n", "13 1973 76 286 239\n", "14 1974 86 231 202\n", "15 1975 90 284 243\n", "16 1976 76 190 175\n", "17 1977 87 257 225\n", "18 1978 88 128 133\n", "19 1979 87 218 199\n", "20 1980 81 206 184\n", "21 1981 74 175 160\n", "22 1982 85 202 187\n", "23 1983 71 130 126\n", "24 1984 80 225 200\n", "25 1985 72 196 173\n", "26 1986 76 261 222\n", "27 1987 85 111 121\n", "28 1988 83 247 210\n", "29 1989 86 137 142\n", "30 1990 82 159 152\n", "31 1991 77 172 160\n", "32 1992 74 280 231\n", "33 1993 70 291 238\n", "34 1994 77 126 125\n", "35 1995 89 191 178\n", "36 1996 83 298 248\n", "37 1997 80 282 237\n", "38 1998 86 219 195\n", "39 1999 72 143 134\n", "40 2000 79 262 221\n", "41 2001 85 189 175\n", "42 2002 86 205 186\n", "43 2003 72 195 173\n", "44 2004 78 148 146\n", "45 2005 71 262 219\n", "46 2006 88 255 226\n", "47 2007 79 262 221\n", "48 2008 73 198 176\n", "49 2009 86 215 187\n", "50 2010 87 127 129\n" ] } ], "prompt_number": 1 }, { "cell_type": "markdown", "metadata": {}, "source": [ "The import seems to be working properly, so that's good news,\n", "but does anyone have anyone see anything about the code that they don't like?\n", "\n", "That's right.\n", "The variable name I've chosen for the data doesn't really communicate any information to anyone about what it's holding,\n", "which means that when I come back to my code next month to change something I'm going to have a more difficult time understanding what the code is actually doing.\n", "This brings us to one of our first major lessons for the morning,\n", "which is that in order to understand what our code is doing so that we can quickly make changes in the future,\n", "we need to *write code for people, not computers*,\n", "and an important first step is to *use meaningful varible names*." ] }, { "cell_type": "code", "collapsed": false, "input": [ "import pandas as pd\n", "\n", "data = pd.read_csv('A2_mosquito_data.csv')\n", "print data.head()" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ " year temperature rainfall mosquitos\n", "0 1960 82 200 180\n", "1 1961 70 227 194\n", "2 1962 89 231 207\n", "3 1963 74 114 121\n", "4 1964 78 147 140\n" ] } ], "prompt_number": 2 }, { "cell_type": "markdown", "metadata": {}, "source": [ "The `.head()` method lets us just look at the first few rows of the data.\n", "A method is a function attached to an object that operates on that object.\n", "So in this case we can think of it as being equivalent to `head(data)`.\n", "\n", "Everything looks good,\n", "but either global warming has gotten *really* out of control or the temperatures are in degrees Fahrenheit.\n", "Let's convert them to Celcius before we get started.\n", "\n", "We don't need to reimport the data in our new cell because all of the executed cells in IPython Notebook share the same workspace.\n", "However, it's worth noting that if we close the notebook and then open it again it is necessary to rerun all of the individual blocks of code that a code block relies on before continuing.\n", "To rerun all of the cells in a notebook you can select `Cell -> Run All` from the menu." ] }, { "cell_type": "code", "collapsed": false, "input": [ "data['temperature'] = (data['temperature'] - 32) * 5 / 9.0\n", "print data.head()" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ " year temperature rainfall mosquitos\n", "0 1960 27.777778 200 180\n", "1 1961 21.111111 227 194\n", "2 1962 31.666667 231 207\n", "3 1963 23.333333 114 121\n", "4 1964 25.555556 147 140\n" ] } ], "prompt_number": 3 }, { "cell_type": "markdown", "metadata": {}, "source": [ "That's better.\n", "Now let's go ahead and conduct a regression on the data.\n", "We'll use the `statsmodels` library to conduct the regression." ] }, { "cell_type": "code", "collapsed": false, "input": [ "import statsmodels.api as sm\n", "\n", "regr_results = sm.OLS.from_formula('mosquitos ~ temperature + rainfall', data).fit()\n", "regr_results.summary()" ], "language": "python", "metadata": {}, "outputs": [ { "html": [ "\n", "\n", "\n", " \n", "\n", "\n", " \n", "\n", "\n", " \n", "\n", "\n", " \n", "\n", "\n", " \n", "\n", "\n", " \n", "\n", "\n", " \n", "\n", "\n", " \n", "\n", "
OLS Regression Results
Dep. Variable: mosquitos R-squared: 0.997
Model: OLS Adj. R-squared: 0.997
Method: Least Squares F-statistic: 7889.
Date: Sat, 18 Jan 2014 Prob (F-statistic): 3.68e-61
Time: 13:10:18 Log-Likelihood: -111.54
No. Observations: 51 AIC: 229.1
Df Residuals: 48 BIC: 234.9
Df Model: 2
\n", "\n", "\n", " \n", "\n", "\n", " \n", "\n", "\n", " \n", "\n", "\n", " \n", "\n", "
coef std err t P>|t| [95.0% Conf. Int.]
Intercept 17.5457 2.767 6.341 0.000 11.983 23.109
temperature 0.8719 0.092 9.457 0.000 0.687 1.057
rainfall 0.6967 0.006 125.385 0.000 0.686 0.708
\n", "\n", "\n", " \n", "\n", "\n", " \n", "\n", "\n", " \n", "\n", "\n", " \n", "\n", "
Omnibus: 1.651 Durbin-Watson: 1.872
Prob(Omnibus): 0.438 Jarque-Bera (JB): 0.906
Skew: -0.278 Prob(JB): 0.636
Kurtosis: 3.343 Cond. No. 1.92e+03
" ], "metadata": {}, "output_type": "pyout", "prompt_number": 4, "text": [ "\n", "\"\"\"\n", " OLS Regression Results \n", "==============================================================================\n", "Dep. Variable: mosquitos R-squared: 0.997\n", "Model: OLS Adj. R-squared: 0.997\n", "Method: Least Squares F-statistic: 7889.\n", "Date: Sat, 18 Jan 2014 Prob (F-statistic): 3.68e-61\n", "Time: 13:10:18 Log-Likelihood: -111.54\n", "No. Observations: 51 AIC: 229.1\n", "Df Residuals: 48 BIC: 234.9\n", "Df Model: 2 \n", "===============================================================================\n", " coef std err t P>|t| [95.0% Conf. Int.]\n", "-------------------------------------------------------------------------------\n", "Intercept 17.5457 2.767 6.341 0.000 11.983 23.109\n", "temperature 0.8719 0.092 9.457 0.000 0.687 1.057\n", "rainfall 0.6967 0.006 125.385 0.000 0.686 0.708\n", "==============================================================================\n", "Omnibus: 1.651 Durbin-Watson: 1.872\n", "Prob(Omnibus): 0.438 Jarque-Bera (JB): 0.906\n", "Skew: -0.278 Prob(JB): 0.636\n", "Kurtosis: 3.343 Cond. No. 1.92e+03\n", "==============================================================================\n", "\n", "Warnings:\n", "[1] The condition number is large, 1.92e+03. This might indicate that there are\n", "strong multicollinearity or other numerical problems.\n", "\"\"\"" ] } ], "prompt_number": 4 }, { "cell_type": "markdown", "metadata": {}, "source": [ "As you can see `statsmodels` lets us use the names of the columns in our dataframe\n", "to clearly specify the form of the statistical model we want to fit.\n", "This also makes the code more readable since the model we are fitting is written in a nice,\n", "human readable, manner.\n", "The `summary` method gives us a visual representation of the results.\n", "This summary is nice to look at, but it isn't really useful for doing more computation,\n", "so we can look up particular values related to the regression using the `regr_results` attributes.\n", "These are variables that are attached to `regr_results`." ] }, { "cell_type": "code", "collapsed": false, "input": [ "print regr_results.params\n", "print regr_results.rsquared" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "Intercept 17.545739\n", "temperature 0.871943\n", "rainfall 0.696717\n", "dtype: float64\n", "0.996966873691\n" ] } ], "prompt_number": 5 }, { "cell_type": "markdown", "metadata": {}, "source": [ "If we want to hold onto these values for later we can assign them to variables:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "parameters = regr_results.params\n", "rsquared = regr_results.rsquared" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 6 }, { "cell_type": "markdown", "metadata": {}, "source": [ "And then we can plot the observed data against the values predicted by our regression to visualize the results.\n", "First, remember to tell the notebook that we want our plots to appear in the notebook itself." ] }, { "cell_type": "code", "collapsed": false, "input": [ "%matplotlib inline" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 7 }, { "cell_type": "code", "collapsed": false, "input": [ "import matplotlib.pyplot as plt\n", "\n", "predicted = parameters[0] + parameters[1] * data['temperature'] + parameters[2] * data['rainfall']\n", "plt.plot(predicted, data['mosquitos'], 'ro')\n", "min_mosquitos, max_mosquitos = min(data['mosquitos']), max(data['mosquitos'])\n", "plt.plot([min_mosquitos, max_mosquitos], [min_mosquitos, max_mosquitos], 'k-')" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 8, "text": [ "[]" ] }, { "metadata": {}, "output_type": "display_data", "png": "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\n", "text": [ "" ] } ], "prompt_number": 8 }, { "cell_type": "markdown", "metadata": {}, "source": [ "OK, great.\n", "So putting this all together we now have a piece of code that imports the modules we need,\n", "loads the data into memory, fits a regression to the data,\n", "and stores the parameters and fit of data." ] }, { "cell_type": "code", "collapsed": false, "input": [ "import pandas as pd\n", "import statsmodels.api as sm\n", "import matplotlib.pyplot as plt\n", "\n", "data = pd.read_csv('A2_mosquito_data.csv')\n", "data['temperature'] = (data['temperature'] - 32) * 5 / 9.0\n", "regr_results = sm.OLS.from_formula('mosquitos ~ temperature + rainfall', data).fit()\n", "parameters = regr_results.params\n", "rsquared = regr_results.rsquared\n", "predicted = parameters[0] + parameters[1] * data['temperature'] + parameters[2] * data['rainfall']\n", "plt.plot(predicted, data['mosquitos'], 'ro')\n", "min_mosquitos, max_mosquitos = min(data['mosquitos']), max(data['mosquitos'])\n", "plt.plot([min_mosquitos, max_mosquitos], [min_mosquitos, max_mosquitos], 'k-')\n", "print parameters\n", "print \"R^2 = \", rsquared" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "Intercept 17.545739\n", "temperature 0.871943\n", "rainfall 0.696717\n", "dtype: float64\n", "R^2 = 0.996966873691\n" ] }, { "metadata": {}, "output_type": "display_data", "png": "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\n", "text": [ "" ] } ], "prompt_number": 9 }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Functions" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The next thing we need to do is loop over all of the possible data files,\n", "but in order to do that we're going to need to grow our code some more.\n", "Since our brain can only easily hold 5-7 pieces of information at once,\n", "and our code already has more than that many pieces,\n", "we need to start breaking our code into manageable sized chunks.\n", "This will let us read and understand the code more easily and make it easier to reuse pieces of our code.\n", "We'll do this using functions.\n", "\n", "Functions in Python take the general form\n", "\n", "~~~python\n", "def function_name(inputs):\n", " do stuff\n", " return output\n", "~~~\n", "\n", "So, if we want to write a function that returns the value of a number squared we could use:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "def square(x):\n", " x_squared = x ** 2\n", " return x_squared\n", "\n", "print \"Four squared is\", square(4)\n", "print \"Five squared is\", square(5)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "Four squared is 16\n", "Five squared is 25\n" ] } ], "prompt_number": 10 }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can also just return the desired value directly." ] }, { "cell_type": "code", "collapsed": false, "input": [ "def square(x):\n", " return x ** 2\n", "\n", "print square(3)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "9\n" ] } ], "prompt_number": 11 }, { "cell_type": "markdown", "metadata": {}, "source": [ "And remember, if we want to use the result of the function later we need to store it somewhere." ] }, { "cell_type": "code", "collapsed": false, "input": [ "two_squared = square(2)\n", "print two_squared" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "4\n" ] } ], "prompt_number": 12 }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "Challenges" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "1\\. Write a function that converts temperature from Fahrenheit to Celcius and use it to replace\n", "\n", "~~~python\n", "data['temperature'] = (data['temperature'] - 32) * 5 / 9.0\n", "~~~\n", "\n", "in our program.\n", "\n", "2\\. Write a function called `analyze()` that takes `data` as an input, performs the regression, makes the observed-predicted plot, and returns `parameters`.\n", "\n", "*Walk through someone's result.\n", "When discussing talk about different names.\n", "E.g., fahr_to_celcius is better than temp_to_celcius since it is explicit both the input and the output.\n", "Talk about the fact that even though this doesn't save us any lines of code it's still easier to read.*" ] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "The call stack" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's take a closer look at what happens when we call fahr_to_celsius(32.0). To make things clearer, we'll start by putting the initial value 32.0 in a variable and store the final result in one as well:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "def fahr_to_celsius(tempF):\n", " tempC = (tempF - 32) * 5 / 9.0\n", " return tempC\n", "\n", "original = 32.0\n", "final = fahr_to_celsius(original)" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 13 }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Call Stack (Initial State)\n", "\n", "When the first three lines of this function are executed the function is created,\n", "but nothing happens.\n", "The function is like a recipe,\n", "it contains the information about how to do something,\n", "but it doesn't do so until you explicitly ask it to.\n", "We then create the variable `original` and assign the value 32.0 to it.\n", "The values `tempF` and `tempC` don't currently exist. \n", "\n", "#### Call Stack Immediately After Function Call\n", "\n", "When we call `fahr_to_celsius`,\n", "Python creates another stack frame to hold fahr_to_celsius's variables.\n", "Upon creation this stack frame only includes the inputs being passed to the function,\n", "so in our case `tempF`.\n", "As the function is executed variables created by the function are stored in the functions stack frame,\n", "so `tempC` is created in the `fahr_to_celsius` stack frame.\n", "\n", "#### Call Stack At End Of Function Call\n", "\n", "When the call to `fahr_to_celsius` returns a value,\n", "Python throws away `fahr_to_celsius`'s stack frame,\n", "including all of the variables it contains,\n", "and creates a new variable\n", "in the original stack frame to hold the temperature in Celsius.\n", "\n", "#### Call Stack After End\n", "\n", "This final stack frame is always there;\n", "it holds the variables we defined outside the functions in our code.\n", "What it doesn't hold is the variables that were in the other stack frames.\n", "If we try to get the value of `tempF` or `tempC` after our functions have finished running,\n", "Python tells us that there's no such thing:\n" ] }, { "cell_type": "code", "collapsed": false, "input": [ "print tempC" ], "language": "python", "metadata": {}, "outputs": [ { "ename": "NameError", "evalue": "name 'tempC' is not defined", "output_type": "pyerr", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[1;31mNameError\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[1;32mprint\u001b[0m \u001b[0mtempC\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[1;31mNameError\u001b[0m: name 'tempC' is not defined" ] } ], "prompt_number": 14 }, { "cell_type": "markdown", "metadata": {}, "source": [ "The reason for this is encapsulation,\n", "and it's one of the key to writing correct, comprehensible programs.\n", "A function's job is to turn several operations into one so that we can think about\n", "a single function call instead of a dozen or a hundred statements each time we want to do something.\n", "That only works if functions don't interfere with each other by potentially changing the same variables;\n", "if they do, we have to pay attention to the details once again,\n", "which quickly overloads our short-term memory." ] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Testing Functions" ] }, { "cell_type": "markdown", "metadata": { "cell_tags": [] }, "source": [ "Once we start putting things into functions so that we can re-use them,\n", "we need to start testing that those functions are working correctly.\n", "The most basic thing we can do is some informal testing to make sure the function is doing what it is supposed to do.\n", "To see how to do this, let's write a function to center the values in a dataset prior to conducting statistical analysis. \n", "Centering means setting the mean of each variable to be the same value, typically zero." ] }, { "cell_type": "code", "collapsed": false, "input": [ "def center(data):\n", " return data - data.mean()" ], "language": "python", "metadata": { "cell_tags": [] }, "outputs": [], "prompt_number": 15 }, { "cell_type": "markdown", "metadata": { "cell_tags": [] }, "source": [ "We could test this on our actual data,\n", "but since we don't know what the values ought to be,\n", "it will be hard to tell if the result was correct.\n", "Instead, let's create a made up data frame where we know what the result should look like." ] }, { "cell_type": "code", "collapsed": false, "input": [ "import pandas as pd\n", "\n", "test_data = pd.DataFrame([[1, 1], [1, 2]])\n", "print test_data" ], "language": "python", "metadata": { "cell_tags": [] }, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ " 0 1\n", "0 1 1\n", "1 1 2\n" ] } ], "prompt_number": 16 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now that we've made some test data we need to figure out what we think the result should be\n", "and we need to do this *before* we run the test.\n", "This is important because we are biased to believe that any result we get back is correct,\n", "and we want to avoid that bias.\n", "This also helps make sure that we are confident in what we want the code to do.\n", "So, what should the result of running `center(data)` be?\n", "\n", "OK, let's go ahead and run the function." ] }, { "cell_type": "code", "collapsed": false, "input": [ "print center(test_data)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ " 0 1\n", "0 0 -0.5\n", "1 0 0.5\n" ] } ], "prompt_number": 17 }, { "cell_type": "markdown", "metadata": { "cell_tags": [] }, "source": [ "That looks right,\n", "so let's try `center` on our real data:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "data = pd.read_csv('A2_mosquito_data.csv')\n", "print center(data)" ], "language": "python", "metadata": { "cell_tags": [] }, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ " year temperature rainfall mosquitos\n", "0 -25 1.607843 -7.039216 -5.235294\n", "1 -24 -10.392157 19.960784 8.764706\n", "2 -23 8.607843 23.960784 21.764706\n", "3 -22 -6.392157 -93.039216 -64.235294\n", "4 -21 -2.392157 -60.039216 -45.235294\n", "5 -20 4.607843 -56.039216 -37.235294\n", "6 -19 5.607843 -35.039216 -23.235294\n", "7 -18 -5.392157 -101.039216 -73.235294\n", "8 -17 -10.392157 68.960784 44.764706\n", "9 -16 5.607843 -42.039216 -23.235294\n", "10 -15 2.607843 14.960784 12.764706\n", "11 -14 -2.392157 89.960784 61.764706\n", "12 -13 6.607843 80.960784 62.764706\n", "13 -12 -4.392157 78.960784 53.764706\n", "14 -11 5.607843 23.960784 16.764706\n", "15 -10 9.607843 76.960784 57.764706\n", "16 -9 -4.392157 -17.039216 -10.235294\n", "17 -8 6.607843 49.960784 39.764706\n", "18 -7 7.607843 -79.039216 -52.235294\n", "19 -6 6.607843 10.960784 13.764706\n", "20 -5 0.607843 -1.039216 -1.235294\n", "21 -4 -6.392157 -32.039216 -25.235294\n", "22 -3 4.607843 -5.039216 1.764706\n", "23 -2 -9.392157 -77.039216 -59.235294\n", "24 -1 -0.392157 17.960784 14.764706\n", "25 0 -8.392157 -11.039216 -12.235294\n", "26 1 -4.392157 53.960784 36.764706\n", "27 2 4.607843 -96.039216 -64.235294\n", "28 3 2.607843 39.960784 24.764706\n", "29 4 5.607843 -70.039216 -43.235294\n", "30 5 1.607843 -48.039216 -33.235294\n", "31 6 -3.392157 -35.039216 -25.235294\n", "32 7 -6.392157 72.960784 45.764706\n", "33 8 -10.392157 83.960784 52.764706\n", "34 9 -3.392157 -81.039216 -60.235294\n", "35 10 8.607843 -16.039216 -7.235294\n", "36 11 2.607843 90.960784 62.764706\n", "37 12 -0.392157 74.960784 51.764706\n", "38 13 5.607843 11.960784 9.764706\n", "39 14 -8.392157 -64.039216 -51.235294\n", "40 15 -1.392157 54.960784 35.764706\n", "41 16 4.607843 -18.039216 -10.235294\n", "42 17 5.607843 -2.039216 0.764706\n", "43 18 -8.392157 -12.039216 -12.235294\n", "44 19 -2.392157 -59.039216 -39.235294\n", "45 20 -9.392157 54.960784 33.764706\n", "46 21 7.607843 47.960784 40.764706\n", "47 22 -1.392157 54.960784 35.764706\n", "48 23 -7.392157 -9.039216 -9.235294\n", "49 24 5.607843 7.960784 1.764706\n", "50 25 6.607843 -80.039216 -56.235294\n" ] } ], "prompt_number": 18 }, { "cell_type": "markdown", "metadata": { "cell_tags": [] }, "source": [ "It's hard to tell from the default output whether the result is correct,\n", "but there are a few simple tests that will reassure us:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "print 'original mean:'\n", "print data.mean()\n", "centered = center(data)\n", "print\n", "print 'mean of centered data:'\n", "centered.mean()" ], "language": "python", "metadata": { "cell_tags": [] }, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "original mean:\n", "year 1985.000000\n", "temperature 80.392157\n", "rainfall 207.039216\n", "mosquitos 185.235294\n", "dtype: float64\n", "\n", "mean of centered data:\n" ] }, { "metadata": {}, "output_type": "pyout", "prompt_number": 19, "text": [ "year 0.000000e+00\n", "temperature 1.393221e-15\n", "rainfall 6.687461e-15\n", "mosquitos -1.337492e-14\n", "dtype: float64" ] } ], "prompt_number": 19 }, { "cell_type": "markdown", "metadata": { "cell_tags": [] }, "source": [ "The mean of the centered data is very close to zero;\n", "it's not quite zero because of floating point precision issues.\n", "We can even go further and check that the standard deviation hasn't changed\n", "(which it shouldn't if we've just centered the data):" ] }, { "cell_type": "code", "collapsed": false, "input": [ "print 'std dev before and after:'\n", "print data.std()\n", "print\n", "print centered.std()" ], "language": "python", "metadata": { "cell_tags": [] }, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "std dev before and after:\n", "year 14.866069\n", "temperature 6.135400\n", "rainfall 56.560396\n", "mosquitos 39.531551\n", "dtype: float64\n", "\n", "year 14.866069\n", "temperature 6.135400\n", "rainfall 56.560396\n", "mosquitos 39.531551\n", "dtype: float64\n" ] } ], "prompt_number": 20 }, { "cell_type": "markdown", "metadata": { "cell_tags": [] }, "source": [ "The standard deviations look the same.\n", "It's still possible that our function is wrong,\n", "but it seems unlikely enough that we we're probably in good shape for now." ] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Documentation" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "OK, the `center` function seems to be working fine.\n", "Does anyone else see anything that's missing before we move on?\n", "\n", "Yes, we should write some [documentation](../../gloss.html#documentation)\n", "to remind ourselves later what it's for and how to use it.\n", "This function may be fairly straightforward,\n", "but in most cases it won't be so easy to remember exactly what a function is doing in a few months.\n", "Just imagine looking at our `analyze` function a few months in the future\n", "and trying to remember exactly what it was doing just based on the code.\n", "\n", "The usual way to put documentation in code is to add [comments](../../gloss.html#comment) like this:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "# center(data): return a new DataFrame containing the original data centered around zero.\n", "def center(data, desired):\n", " return data - data.mean()" ], "language": "python", "metadata": { "cell_tags": [] }, "outputs": [], "prompt_number": 21 }, { "cell_type": "markdown", "metadata": { "cell_tags": [] }, "source": [ "There's a better way to do this in Python.\n", "If the first thing in a function is a string that isn't assigned to a variable,\n", "that string is attached to the function as its documentation:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "def center(data, desired):\n", " \"\"\"Return a new DataFrame containing the original data centered around zero.\"\"\"\n", " return data - data.mean()" ], "language": "python", "metadata": { "cell_tags": [] }, "outputs": [], "prompt_number": 22 }, { "cell_type": "markdown", "metadata": { "cell_tags": [] }, "source": [ "This is better because we can now ask Python's built-in help system to show us the documentation for the function." ] }, { "cell_type": "code", "collapsed": false, "input": [ "help(center)" ], "language": "python", "metadata": { "cell_tags": [] }, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "Help on function center in module __main__:\n", "\n", "center(data, desired)\n", " Return a new DataFrame containing the original data centered around zero.\n", "\n" ] } ], "prompt_number": 23 }, { "cell_type": "markdown", "metadata": { "cell_tags": [] }, "source": [ "A string like this is called a [docstring](../../gloss.html#docstring)\n", "and there are also automatic documentation generators that use these docstrings to produce documentation for users.\n", "We use triple quotes because\n", "it allows us to include multiple lines of text and because it is considered good Python style." ] }, { "cell_type": "code", "collapsed": false, "input": [ "def center(data):\n", " \"\"\"Return a new array containing the original data centered on zero\n", " \n", " Example:\n", " >>> import pandas\n", " >>> data = pandas.DataFrame([[0, 1], [0, 2])\n", " >>> center(data)\n", " 0 1\n", " 0 0 -0.5\n", " 1 0 0.5\n", "\n", " \n", " \"\"\"\n", " return data - data.mean()\n", "\n", "help(center)" ], "language": "python", "metadata": { "cell_tags": [] }, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "Help on function center in module __main__:\n", "\n", "center(data)\n", " Return a new array containing the original data centered on zero\n", " \n", " Example:\n", " >>> import pandas\n", " >>> data = pandas.DataFrame([[0, 1], [0, 2])\n", " >>> center(data)\n", " 0 1\n", " 0 0 -0.5\n", " 1 0 0.5\n", "\n" ] } ], "prompt_number": 24 }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "Challenge" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "1. Test your temperature conversion function to make sure it's working\n", " (think about some temperatures that you easily know the conversion for).\n", "2. Add documentation to both the temperature conversation function and the analysis function." ] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Looping over files" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "So now our code looks something like this:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "import pandas as pd\n", "import statsmodels.api as sm\n", "import matplotlib.pyplot as plt\n", "\n", "def fahr_to_celsius(tempF):\n", " \"\"\"Convert fahrenheit to celsius\"\"\"\n", " tempC = (tempF - 32) * 5 / 9.0\n", " return tempC\n", "\n", "def analyze(data):\n", " \"\"\"Perform regression analysis on mosquito data\n", " \n", " Takes a dataframe as input that includes columns named 'temperature',\n", " 'rainfall', and 'mosquitos'.\n", " \n", " Performs a multiple regression to predict the number of mosquitos.\n", " Creates an observed-predicted plot of the result and\n", " returns the parameters of the regression.\n", " \n", " \"\"\"\n", " regr_results = sm.OLS.from_formula('mosquitos ~ temperature + rainfall', data).fit()\n", " parameters = regr_results.params\n", " predicted = parameters[0] + parameters[1] * data['temperature'] + parameters[2] * data['rainfall']\n", " plt.figure()\n", " plt.plot(predicted, data['mosquitos'], 'ro')\n", " min_mosquitos, max_mosquitos = min(data['mosquitos']), max(data['mosquitos'])\n", " plt.plot([min_mosquitos, max_mosquitos], [min_mosquitos, max_mosquitos], 'k-')\n", " return parameters\n", "\n", "data = pd.read_csv('A2_mosquito_data.csv')\n", "data['temperature'] = fahr_to_celsius(data['temperature'])\n", "regr_results = analyze(data)\n", "print parameters" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "Intercept 17.545739\n", "temperature 0.871943\n", "rainfall 0.696717\n", "dtype: float64\n" ] }, { "metadata": {}, "output_type": "display_data", "png": "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\n", "text": [ "" ] } ], "prompt_number": 25 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now we want to loop over all of the possible data files,\n", "and to do that we need to know their names.\n", "If we only had a dozen files we could write them all down,\n", "but if we have hundreds of files or the filenames change then that won't really work.\n", "Fortunately Python has a built in library to help us find the files we want to work with called `glob`." ] }, { "cell_type": "code", "collapsed": false, "input": [ "import glob\n", "\n", "filenames = glob.glob('*.csv')\n", "print filenames" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "['A1_mosquito_data.csv', 'B2_mosquito_data.csv', 'A3_mosquito_data.csv', 'B1_mosquito_data.csv', 'A2_mosquito_data.csv']\n" ] } ], "prompt_number": 26 }, { "cell_type": "markdown", "metadata": {}, "source": [ "The object returned by `glob` is a list of strings.\n", "A list is a Python data type that holds a group of potentially heterogenous values.\n", "That means it can hold pretty much anything,\n", "including functions." ] }, { "cell_type": "code", "collapsed": false, "input": [ "mylist = [1, 'a', center]\n", "print mylist" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "[1, 'a', ]\n" ] } ], "prompt_number": 27 }, { "cell_type": "markdown", "metadata": {}, "source": [ "In this case all of the values are strings\n", "that contain the names of all of the files that match the expression given to `glob`,\n", "so in this case all of the files with the `.csv` extension.\n", "\n", "Let's restrict the filenames a little more finely,\n", "so that we don't accidentally get any data we don't want,\n", "and print out the filenames one at a time." ] }, { "cell_type": "code", "collapsed": false, "input": [ "filenames =glob.glob('*data.csv')\n", "for filename in filenames:\n", " print filename" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "A1_mosquito_data.csv\n", "B2_mosquito_data.csv\n", "A3_mosquito_data.csv\n", "B1_mosquito_data.csv\n", "A2_mosquito_data.csv\n" ] } ], "prompt_number": 28 }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "Challenge" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Modify your code to loop over all of the files in your directory,\n", "making an observed-predicted plot for each file and printing the parameters." ] } ], "metadata": {} } ] }