{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# 02 - Introduction to Python for Data Analysis\n", "\n", "by [Alejandro Correa Bahnsen](http://www.albahnsen.com/) & [Iván Torroledo](http://www.ivantorroledo.com/)\n", "\n", "version 1.3, June 2018\n", "\n", "## Part of the class [Applied Deep Learning](https://github.com/albahnsen/AppliedDeepLearningClass)\n", "\n", "This notebook is licensed under a [Creative Commons Attribution-ShareAlike 3.0 Unported License](http://creativecommons.org/licenses/by-sa/3.0/deed.en_US). Special thanks goes to [Rick Muller](http://www.cs.sandia.gov/~rmuller/), Sandia National Laboratories" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Why Python?\n", "Python is the programming language of choice for many scientists to a large degree because it offers a great deal of power to analyze and model scientific data with relatively little overhead in terms of learning, installation or development time. It is a language you can pick up in a weekend, and use for the rest of one's life.\n", "\n", "The [Python Tutorial](http://docs.python.org/3/tutorial/) is a great place to start getting a feel for the language. To complement this material, I taught a [Python Short Course](http://www.wag.caltech.edu/home/rpm/python_course/) years ago to a group of computational chemists during a time that I was worried the field was moving too much in the direction of using canned software rather than developing one's own methods. I wanted to focus on what working scientists needed to be more productive: parsing output of other programs, building simple models, experimenting with object oriented programming, extending the language with C, and simple GUIs. \n", "\n", "I'm trying to do something very similar here, to cut to the chase and focus on what scientists need. In the last year or so, the [Jupyter Project](http://jupyter.org) has put together a notebook interface that I have found incredibly valuable. A large number of people have released very good IPython Notebooks that I have taken a huge amount of pleasure reading through. Some ones that I particularly like include:\n", "\n", "* Rick Muller [A Crash Course in Python for Scientists](http://nbviewer.jupyter.org/gist/rpmuller/5920182)\n", "* Rob Johansson's [excellent notebooks](http://jrjohansson.github.io/), including [Scientific Computing with Python](https://github.com/jrjohansson/scientific-python-lectures) and [Computational Quantum Physics with QuTiP](https://github.com/jrjohansson/qutip-lectures) lectures;\n", "* [XKCD style graphs in matplotlib](http://nbviewer.ipython.org/url/jakevdp.github.com/downloads/notebooks/XKCD_plots.ipynb);\n", "* [A collection of Notebooks for using IPython effectively](https://github.com/ipython/ipython/tree/master/examples/notebooks#a-collection-of-notebooks-for-using-ipython-effectively)\n", "* [A gallery of interesting IPython Notebooks](https://github.com/ipython/ipython/wiki/A-gallery-of-interesting-IPython-Notebooks)\n", "\n", "I find Jupyter notebooks an easy way both to get important work done in my everyday job, as well as to communicate what I've done, how I've done it, and why it matters to my coworkers. In the interest of putting more notebooks out into the wild for other people to use and enjoy, I thought I would try to recreate some of what I was trying to get across in the original Python Short Course, updated by 15 years of Python, Numpy, Scipy, Pandas, Matplotlib, and IPython development, as well as my own experience in using Python almost every day of this time." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Why Python for Data Analysis?\n", "\n", "- Python is great for scripting and applications.\n", "- The `pandas` library offers imporved library support.\n", "- Scraping, web APIs\n", "- Strong High Performance Computation support\n", " - Load balanceing tasks\n", " - MPI, GPU\n", " - MapReduce\n", "- Strong support for abstraction\n", " - Intel MKL\n", " - HDF5\n", "- Environment" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## But we already know R\n", "\n", "...Which is better? Hard to answer\n", "\n", "http://www.kdnuggets.com/2015/05/r-vs-python-data-science.html\n", "\n", "http://www.kdnuggets.com/2015/03/the-grammar-data-science-python-vs-r.html\n", "\n", "https://www.datacamp.com/community/tutorials/r-or-python-for-data-analysis\n", "\n", "https://www.dataquest.io/blog/python-vs-r/\n", "\n", "http://www.dataschool.io/python-or-r-for-data-science/" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## What You Need to Install\n", "\n", "There are two branches of current releases in Python: the older-syntax Python 2, and the newer-syntax Python 3. This schizophrenia is largely intentional: when it became clear that some non-backwards-compatible changes to the language were necessary, the Python dev-team decided to go through a five-year (or so) transition, during which the new language features would be introduced and the old language was still actively maintained, to make such a transition as easy as possible. \n", "\n", "Nonetheless, I'm going to write these notes with Python 3 in mind, since this is the version of the language that I use in my day-to-day job, and am most comfortable with. \n", "\n", "With this in mind, these notes assume you have a Python distribution that includes:\n", "\n", "* [Python](http://www.python.org) version 3.5;\n", "* [Numpy](http://www.numpy.org), the core numerical extensions for linear algebra and multidimensional arrays;\n", "* [Scipy](http://www.scipy.org), additional libraries for scientific programming;\n", "* [Matplotlib](http://matplotlib.sf.net), excellent plotting and graphing libraries;\n", "* [IPython](http://ipython.org), with the additional libraries required for the notebook interface.\n", "* [Pandas](http://pandas.pydata.org/), Python version of R dataframe\n", "* [scikit-learn](http://scikit-learn.org), Machine learning library!\n", "\n", "A good, easy to install option that supports Mac, Windows, and Linux, and that has all of these packages (and much more) is the [Anaconda](https://www.continuum.io/)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Checking your installation\n", "\n", "You can run the following code to check the versions of the packages on your system:\n", "\n", "(in IPython notebook, press `shift` and `return` together to execute the contents of a cell)" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Python version: 3.6.4 |Anaconda, Inc.| (default, Jan 16 2018, 18:10:19) \n", "[GCC 7.2.0]\n", "IPython: 6.2.1\n", "numpy: 1.14.0\n", "scipy: 1.0.0\n", "matplotlib: 2.1.2\n", "pandas: 0.22.0\n", "scikit-learn: 0.19.1\n" ] } ], "source": [ "import sys\n", "\n", "print('Python version:', sys.version)\n", "\n", "import IPython\n", "print('IPython:', IPython.__version__)\n", "\n", "import numpy\n", "print('numpy:', numpy.__version__)\n", "\n", "import scipy\n", "print('scipy:', scipy.__version__)\n", "\n", "import matplotlib\n", "print('matplotlib:', matplotlib.__version__)\n", "\n", "import pandas\n", "print('pandas:', pandas.__version__)\n", "\n", "import sklearn\n", "print('scikit-learn:', sklearn.__version__)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# I. Python Overview\n", "This is a quick introduction to Python. There are lots of other places to learn the language more thoroughly. I have collected a list of useful links, including ones to other learning resources, at the end of this notebook. If you want a little more depth, [Python Tutorial](http://docs.python.org/2/tutorial/) is a great place to start, as is Zed Shaw's [Learn Python the Hard Way](http://learnpythonthehardway.org/book/).\n", "\n", "The lessons that follow make use of the IPython notebooks. There's a good introduction to notebooks [in the IPython notebook documentation](http://ipython.org/notebook.html) that even has a [nice video](http://www.youtube.com/watch?v=H6dLGQw9yFQ#!) on how to use the notebooks. You should probably also flip through the [IPython tutorial](http://ipython.org/ipython-doc/dev/interactive/tutorial.html) in your copious free time.\n", "\n", "Briefly, notebooks have code cells (that are generally followed by result cells) and text cells. The text cells are the stuff that you're reading now. The code cells start with \"In []:\" with some number generally in the brackets. If you put your cursor in the code cell and hit Shift-Enter, the code will run in the Python interpreter and the result will print out in the output cell. You can then change things around and see whether you understand what's going on. If you need to know more, see the [IPython notebook documentation](http://ipython.org/notebook.html) or the [IPython tutorial](http://ipython.org/ipython-doc/dev/interactive/tutorial.html)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Using Python as a Calculator" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Many of the things I used to use a calculator for, I now use Python for:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "4" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "2+2" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "5.0" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(50-5*6)/4" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "(If you're typing this into an IPython notebook, or otherwise using notebook file, you hit shift-Enter to evaluate a cell.)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In the last few lines, we have sped by a lot of things that we should stop for a moment and explore a little more fully. We've seen, however briefly, two different data types: **integers**, also known as *whole numbers* to the non-programming world, and **floating point numbers**, also known (incorrectly) as *decimal numbers* to the rest of the world.\n", "\n", "We've also seen the first instance of an **import** statement. Python has a huge number of libraries included with the distribution. To keep things simple, most of these variables and functions are not accessible from a normal Python interactive session. Instead, you have to import the name. For example, there is a **math** module containing many useful functions. To access, say, the square root function, you can either first\n", "\n", " from math import sqrt\n", "\n", "and then" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "ename": "NameError", "evalue": "name 'sqrt' is not defined", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0msqrt\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m81\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mNameError\u001b[0m: name 'sqrt' is not defined" ] } ], "source": [ "sqrt(81)" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "9.0" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from math import sqrt\n", "sqrt(81)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "or you can simply import the math library itself" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "9.0" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import math\n", "math.sqrt(81)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can define variables using the equals (=) sign:" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1256.6370614359173" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "radius = 20\n", "pi = math.pi\n", "area = pi * radius ** 2 \n", "area" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can name a variable *almost* anything you want. It needs to start with an alphabetical character or \"\\_\", can contain alphanumeric charcters plus underscores (\"\\_\"). Certain words, however, are reserved for the language:\n", "\n", " and, as, assert, break, class, continue, def, del, elif, else, except, \n", " exec, finally, for, from, global, if, import, in, is, lambda, not, or,\n", " pass, print, raise, return, try, while, with, yield\n", "\n", "Trying to define a variable using one of these will result in a syntax error:" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "ename": "SyntaxError", "evalue": "invalid syntax (, line 1)", "output_type": "error", "traceback": [ "\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m return = 0\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n" ] } ], "source": [ "return = 0" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The [Python Tutorial](http://docs.python.org/2/tutorial/introduction.html#using-python-as-a-calculator) has more on using Python as an interactive shell. The [IPython tutorial](http://ipython.org/ipython-doc/dev/interactive/tutorial.html) makes a nice complement to this, since IPython has a much more sophisticated iteractive shell." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Strings\n", "Strings are lists of printable characters, and can be defined using either single quotes" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'Hello, World!'" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "'Hello, World!'" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "or double quotes" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'Hello, World!'" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "\"Hello, World!\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Just like the other two data objects we're familiar with (ints and floats), you can assign a string to a variable" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "collapsed": true }, "outputs": [], "source": [ "greeting = \"Hello, World!\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The **print** statement is often used for printing character strings:" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Hello, World!\n" ] } ], "source": [ "print(greeting)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "But it can also print data types other than strings:" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "ename": "TypeError", "evalue": "must be str, not float", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"The area is \"\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0marea\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mTypeError\u001b[0m: must be str, not float" ] } ], "source": [ "print(\"The area is \" + area)" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The area is 1256.6370614359173\n" ] } ], "source": [ "print(\"The area is \" + str(area))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In the above snipped, the number 600 (stored in the variable \"area\") is converted into a string before being printed out." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can use the + operator to concatenate strings together:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Don't forget the space between the strings, if you want one there. " ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Hello, World!\n" ] } ], "source": [ "statement = \"Hello, \" + \"World!\"\n", "print(statement)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If you have a lot of words to concatenate together, there are other, more efficient ways to do this. But this is fine for linking a few strings together." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Lists\n", "Very often in a programming language, one wants to keep a group of similar items together. Python does this using a data type called **lists**." ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "collapsed": true }, "outputs": [], "source": [ "days_of_the_week = [\"Sunday\",\"Monday\",\"Tuesday\",\"Wednesday\",\"Thursday\",\"Friday\",\"Saturday\"]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can access members of the list using the **index** of that item:" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'Tuesday'" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "days_of_the_week[2]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Python lists, like C, but unlike Fortran, use 0 as the index of the first element of a list. Thus, in this example, the 0 element is \"Sunday\", 1 is \"Monday\", and so on. If you need to access the *n*th element from the end of the list, you can use a negative index. For example, the -1 element of a list is the last element:" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'Saturday'" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "days_of_the_week[-1]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can add additional items to the list using the .append() command:" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['Fortran', 'C', 'C++', 'Python']\n" ] } ], "source": [ "languages = [\"Fortran\",\"C\",\"C++\"]\n", "languages.append(\"Python\")\n", "print(languages)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The **range()** command is a convenient way to make sequential lists of numbers:" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "list(range(10))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note that range(n) starts at 0 and gives the sequential list of integers less than n. If you want to start at a different number, use range(start,stop)" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[2, 3, 4, 5, 6, 7]" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "list(range(2,8))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The lists created above with range have a *step* of 1 between elements. You can also give a fixed step size via a third command:" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "evens = list(range(0,20,2))\n", "evens" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "6" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "evens[3]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Lists do not have to hold the same data type. For example," ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['Today', 7, 99.3, '']" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[\"Today\",7,99.3,\"\"]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "However, it's good (but not essential) to use lists for similar objects that are somehow logically connected. If you want to group different data types together into a composite data object, it's best to use **tuples**, which we will learn about below.\n", "\n", "You can find out how long a list is using the **len()** command:" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Help on built-in function len in module builtins:\n", "\n", "len(obj, /)\n", " Return the number of items in a container.\n", "\n" ] } ], "source": [ "help(len)" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "10" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "len(evens)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Iteration, Indentation, and Blocks\n", "One of the most useful things you can do with lists is to *iterate* through them, i.e. to go through each element one at a time. To do this in Python, we use the **for** statement:" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Sunday\n", "Monday\n", "Tuesday\n", "Wednesday\n", "Thursday\n", "Friday\n", "Saturday\n" ] } ], "source": [ "for day in days_of_the_week:\n", " print(day)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This code snippet goes through each element of the list called **days_of_the_week** and assigns it to the variable **day**. It then executes everything in the indented block (in this case only one line of code, the print statement) using those variable assignments. When the program has gone through every element of the list, it exists the block.\n", "\n", "(Almost) every programming language defines blocks of code in some way. In Fortran, one uses END statements (ENDDO, ENDIF, etc.) to define code blocks. In C, C++, and Perl, one uses curly braces {} to define these blocks.\n", "\n", "Python uses a colon (\":\"), followed by indentation level to define code blocks. Everything at a higher level of indentation is taken to be in the same block. In the above example the block was only a single line, but we could have had longer blocks as well:" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Today is Sunday\n", "Today is Monday\n", "Today is Tuesday\n", "Today is Wednesday\n", "Today is Thursday\n", "Today is Friday\n", "Today is Saturday\n" ] } ], "source": [ "for day in days_of_the_week:\n", " statement = \"Today is \" + day\n", " print(statement)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The **range()** command is particularly useful with the **for** statement to execute loops of a specified length:" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The square of 0 is 0\n", "The square of 1 is 1\n", "The square of 2 is 4\n", "The square of 3 is 9\n", "The square of 4 is 16\n", "The square of 5 is 25\n", "The square of 6 is 36\n", "The square of 7 is 49\n", "The square of 8 is 64\n", "The square of 9 is 81\n", "The square of 10 is 100\n", "The square of 11 is 121\n", "The square of 12 is 144\n", "The square of 13 is 169\n", "The square of 14 is 196\n", "The square of 15 is 225\n", "The square of 16 is 256\n", "The square of 17 is 289\n", "The square of 18 is 324\n", "The square of 19 is 361\n" ] } ], "source": [ "for i in range(20):\n", " print(\"The square of \",i,\" is \",i*i)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Slicing\n", "Lists and strings have something in common that you might not suspect: they can both be treated as sequences. You already know that you can iterate through the elements of a list. You can also iterate through the letters in a string:" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "S\n", "u\n", "n\n", "d\n", "a\n", "y\n" ] } ], "source": [ "for letter in \"Sunday\":\n", " print(letter)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This is only occasionally useful. Slightly more useful is the *slicing* operation, which you can also use on any sequence. We already know that we can use *indexing* to get the first element of a list:" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'Sunday'" ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], "source": [ "days_of_the_week[0]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If we want the list containing the first two elements of a list, we can do this via" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['Sunday', 'Monday']" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "days_of_the_week[0:2]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "or simply" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['Sunday', 'Monday']" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "days_of_the_week[:2]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If we want the last items of the list, we can do this with negative slicing:" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['Friday', 'Saturday']" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "days_of_the_week[-2:]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "which is somewhat logically consistent with negative indices accessing the last elements of the list.\n", "\n", "You can do:" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']\n" ] } ], "source": [ "workdays = days_of_the_week[1:6]\n", "print(workdays)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Since strings are sequences, you can also do this to them:" ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Sun\n" ] } ], "source": [ "day = \"Sunday\"\n", "abbreviation = day[:3]\n", "print(abbreviation)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If we really want to get fancy, we can pass a third element into the slice, which specifies a step length (just like a third argument to the **range()** function specifies the step):" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38]" ] }, "execution_count": 37, "metadata": {}, "output_type": "execute_result" } ], "source": [ "numbers = list(range(0,40))\n", "evens = numbers[2::2]\n", "evens" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note that in this example I was even able to omit the second argument, so that the slice started at 2, went to the end of the list, and took every second element, to generate the list of even numbers less that 40." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Booleans and Truth Testing\n", "We have now learned a few data types. We have integers and floating point numbers, strings, and lists to contain them. We have also learned about lists, a container that can hold any data type. We have learned to print things out, and to iterate over items in lists. We will now learn about **boolean** variables that can be either True or False.\n", "\n", "We invariably need some concept of *conditions* in programming to control branching behavior, to allow a program to react differently to different situations. If it's Monday, I'll go to work, but if it's Sunday, I'll sleep in. To do this in Python, we use a combination of **boolean** variables, which evaluate to either True or False, and **if** statements, that control branching based on boolean values." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For example:" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Sleep in\n" ] } ], "source": [ "if day == \"Sunday\":\n", " print(\"Sleep in\")\n", "else:\n", " print(\"Go to work\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "(Quick quiz: why did the snippet print \"Go to work\" here? What is the variable \"day\" set to?)\n", "\n", "Let's take the snippet apart to see what happened. First, note the statement" ] }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 39, "metadata": {}, "output_type": "execute_result" } ], "source": [ "day == \"Sunday\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If we evaluate it by itself, as we just did, we see that it returns a boolean value, False. The \"==\" operator performs *equality testing*. If the two items are equal, it returns True, otherwise it returns False. In this case, it is comparing two variables, the string \"Sunday\", and whatever is stored in the variable \"day\", which, in this case, is the other string \"Saturday\". Since the two strings are not equal to each other, the truth test has the false value." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The if statement that contains the truth test is followed by a code block (a colon followed by an indented block of code). If the boolean is true, it executes the code in that block. Since it is false in the above example, we don't see that code executed.\n", "\n", "The first block of code is followed by an **else** statement, which is executed if nothing else in the above if statement is true. Since the value was false, this code is executed, which is why we see \"Go to work\".\n", "\n", "You can compare any data types in Python:" ] }, { "cell_type": "code", "execution_count": 40, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 40, "metadata": {}, "output_type": "execute_result" } ], "source": [ "1 == 2" ] }, { "cell_type": "code", "execution_count": 41, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 41, "metadata": {}, "output_type": "execute_result" } ], "source": [ "50 == 2*25" ] }, { "cell_type": "code", "execution_count": 42, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 42, "metadata": {}, "output_type": "execute_result" } ], "source": [ "3 < 3.14159" ] }, { "cell_type": "code", "execution_count": 43, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 43, "metadata": {}, "output_type": "execute_result" } ], "source": [ "1 == 1.0" ] }, { "cell_type": "code", "execution_count": 44, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 44, "metadata": {}, "output_type": "execute_result" } ], "source": [ "1 != 0" ] }, { "cell_type": "code", "execution_count": 45, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 45, "metadata": {}, "output_type": "execute_result" } ], "source": [ "1 <= 2" ] }, { "cell_type": "code", "execution_count": 46, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 46, "metadata": {}, "output_type": "execute_result" } ], "source": [ "1 >= 1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We see a few other boolean operators here, all of which which should be self-explanatory. Less than, equality, non-equality, and so on.\n", "\n", "Particularly interesting is the 1 == 1.0 test, which is true, since even though the two objects are different data types (integer and floating point number), they have the same *value*. There is another boolean operator **is**, that tests whether two objects are the same object:" ] }, { "cell_type": "code", "execution_count": 47, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 47, "metadata": {}, "output_type": "execute_result" } ], "source": [ "1 is 1.0" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can do boolean tests on lists as well:" ] }, { "cell_type": "code", "execution_count": 48, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 48, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[1,2,3] == [1,2,4]" ] }, { "cell_type": "code", "execution_count": 49, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 49, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[1,2,3] < [1,2,4]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Finally, note that you can also string multiple comparisons together, which can result in very intuitive tests:" ] }, { "cell_type": "code", "execution_count": 50, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 50, "metadata": {}, "output_type": "execute_result" } ], "source": [ "hours = 5\n", "0 < hours < 24" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If statements can have **elif** parts (\"else if\"), in addition to if/else parts. For example:" ] }, { "cell_type": "code", "execution_count": 51, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Sleep in\n" ] } ], "source": [ "if day == \"Sunday\":\n", " print(\"Sleep in\")\n", "elif day == \"Saturday\":\n", " print(\"Do chores\")\n", "else:\n", " print(\"Go to work\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Of course we can combine if statements with for loops, to make a snippet that is almost interesting:" ] }, { "cell_type": "code", "execution_count": 52, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Today is Sunday\n", " Sleep in\n", "Today is Monday\n", " Go to work\n", "Today is Tuesday\n", " Go to work\n", "Today is Wednesday\n", " Go to work\n", "Today is Thursday\n", " Go to work\n", "Today is Friday\n", " Go to work\n", "Today is Saturday\n", " Do chores\n" ] } ], "source": [ "for day in days_of_the_week:\n", " statement = \"Today is \" + day\n", " print(statement)\n", " if day == \"Sunday\":\n", " print(\" Sleep in\")\n", " elif day == \"Saturday\":\n", " print(\" Do chores\")\n", " else:\n", " print(\" Go to work\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This is something of an advanced topic, but ordinary data types have boolean values associated with them, and, indeed, in early versions of Python there was not a separate boolean object. Essentially, anything that was a 0 value (the integer or floating point 0, an empty string \"\", or an empty list []) was False, and everything else was true. You can see the boolean value of any data object using the **bool()** function." ] }, { "cell_type": "code", "execution_count": 53, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 53, "metadata": {}, "output_type": "execute_result" } ], "source": [ "bool(1)" ] }, { "cell_type": "code", "execution_count": 54, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 54, "metadata": {}, "output_type": "execute_result" } ], "source": [ "bool(0)" ] }, { "cell_type": "code", "execution_count": 55, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 55, "metadata": {}, "output_type": "execute_result" } ], "source": [ "bool([\"This \",\" is \",\" a \",\" list\"])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Code Example: The Fibonacci Sequence\n", "The [Fibonacci sequence](http://en.wikipedia.org/wiki/Fibonacci_number) is a sequence in math that starts with 0 and 1, and then each successive entry is the sum of the previous two. Thus, the sequence goes 0,1,1,2,3,5,8,13,21,34,55,89,...\n", "\n", "A very common exercise in programming books is to compute the Fibonacci sequence up to some number **n**. First I'll show the code, then I'll discuss what it is doing." ] }, { "cell_type": "code", "execution_count": 56, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]\n" ] } ], "source": [ "n = 10\n", "sequence = [0,1]\n", "for i in range(2,n): # This is going to be a problem if we ever set n <= 2!\n", " sequence.append(sequence[i-1]+sequence[i-2])\n", "print(sequence)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's go through this line by line. First, we define the variable **n**, and set it to the integer 20. **n** is the length of the sequence we're going to form, and should probably have a better variable name. We then create a variable called **sequence**, and initialize it to the list with the integers 0 and 1 in it, the first two elements of the Fibonacci sequence. We have to create these elements \"by hand\", since the iterative part of the sequence requires two previous elements.\n", "\n", "We then have a for loop over the list of integers from 2 (the next element of the list) to **n** (the length of the sequence). After the colon, we see a hash tag \"#\", and then a **comment** that if we had set **n** to some number less than 2 we would have a problem. Comments in Python start with #, and are good ways to make notes to yourself or to a user of your code explaining why you did what you did. Better than the comment here would be to test to make sure the value of **n** is valid, and to complain if it isn't; we'll try this later.\n", "\n", "In the body of the loop, we append to the list an integer equal to the sum of the two previous elements of the list.\n", "\n", "After exiting the loop (ending the indentation) we then print out the whole list. That's it!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Functions\n", "We might want to use the Fibonacci snippet with different sequence lengths. We could cut an paste the code into another cell, changing the value of **n**, but it's easier and more useful to make a function out of the code. We do this with the **def** statement in Python:" ] }, { "cell_type": "code", "execution_count": 57, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def fibonacci(sequence_length):\n", " \"Return the Fibonacci sequence of length *sequence_length*\"\n", " sequence = [0,1]\n", " if sequence_length < 1:\n", " print(\"Fibonacci sequence only defined for length 1 or greater\")\n", " return\n", " if 0 < sequence_length < 3:\n", " return sequence[:sequence_length]\n", " for i in range(2,sequence_length): \n", " sequence.append(sequence[i-1]+sequence[i-2])\n", " return sequence" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can now call **fibonacci()** for different sequence_lengths:" ] }, { "cell_type": "code", "execution_count": 58, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[0, 1]" ] }, "execution_count": 58, "metadata": {}, "output_type": "execute_result" } ], "source": [ "fibonacci(2)" ] }, { "cell_type": "code", "execution_count": 59, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]" ] }, "execution_count": 59, "metadata": {}, "output_type": "execute_result" } ], "source": [ "fibonacci(12)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We've introduced a several new features here. First, note that the function itself is defined as a code block (a colon followed by an indented block). This is the standard way that Python delimits things. Next, note that the first line of the function is a single string. This is called a **docstring**, and is a special kind of comment that is often available to people using the function through the python command line:" ] }, { "cell_type": "code", "execution_count": 60, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Help on function fibonacci in module __main__:\n", "\n", "fibonacci(sequence_length)\n", " Return the Fibonacci sequence of length *sequence_length*\n", "\n" ] } ], "source": [ "help(fibonacci)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If you define a docstring for all of your functions, it makes it easier for other people to use them, since they can get help on the arguments and return values of the function.\n", "\n", "Next, note that rather than putting a comment in about what input values lead to errors, we have some testing of these values, followed by a warning if the value is invalid, and some conditional code to handle special cases." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Two More Data Structures: Tuples and Dictionaries\n", "Before we end the Python overview, I wanted to touch on two more data structures that are very useful (and thus very common) in Python programs.\n", "\n", "A **tuple** is a sequence object like a list or a string. It's constructed by grouping a sequence of objects together with commas, either without brackets, or with parentheses:" ] }, { "cell_type": "code", "execution_count": 61, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(1, 2, 'hi', 9.0)" ] }, "execution_count": 61, "metadata": {}, "output_type": "execute_result" } ], "source": [ "t = (1,2,'hi',9.0)\n", "t" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Tuples are like lists, in that you can access the elements using indices:" ] }, { "cell_type": "code", "execution_count": 62, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "2" ] }, "execution_count": 62, "metadata": {}, "output_type": "execute_result" } ], "source": [ "t[1]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "However, tuples are *immutable*, you can't append to them or change the elements of them:" ] }, { "cell_type": "code", "execution_count": 63, "metadata": {}, "outputs": [ { "ename": "AttributeError", "evalue": "'tuple' object has no attribute 'append'", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m7\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mAttributeError\u001b[0m: 'tuple' object has no attribute 'append'" ] } ], "source": [ "t.append(7)" ] }, { "cell_type": "code", "execution_count": 64, "metadata": {}, "outputs": [ { "ename": "TypeError", "evalue": "'tuple' object does not support item assignment", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mt\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m77\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mTypeError\u001b[0m: 'tuple' object does not support item assignment" ] } ], "source": [ "t[1]=77" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Tuples are useful anytime you want to group different pieces of data together in an object, but don't want to create a full-fledged class (see below) for them. For example, let's say you want the Cartesian coordinates of some objects in your program. Tuples are a good way to do this:" ] }, { "cell_type": "code", "execution_count": 65, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "('Bob', 0.0, 21.0)" ] }, "execution_count": 65, "metadata": {}, "output_type": "execute_result" } ], "source": [ "('Bob',0.0,21.0)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Again, it's not a necessary distinction, but one way to distinguish tuples and lists is that tuples are a collection of different things, here a name, and x and y coordinates, whereas a list is a collection of similar things, like if we wanted a list of those coordinates:" ] }, { "cell_type": "code", "execution_count": 66, "metadata": { "collapsed": true }, "outputs": [], "source": [ "positions = [\n", " ('Bob',0.0,21.0),\n", " ('Cat',2.5,13.1),\n", " ('Dog',33.0,1.2)\n", " ]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Tuples can be used when functions return more than one value. Say we wanted to compute the smallest x- and y-coordinates of the above list of objects. We could write:" ] }, { "cell_type": "code", "execution_count": 67, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0.0 1.2\n" ] } ], "source": [ "def minmax(objects):\n", " minx = 1e20 # These are set to really big numbers\n", " miny = 1e20\n", " for obj in objects:\n", " name,x,y = obj\n", " if x < minx: \n", " minx = x\n", " if y < miny:\n", " miny = y\n", " return minx,miny\n", "\n", "x,y = minmax(positions)\n", "print(x,y)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Dictionaries** are an object called \"mappings\" or \"associative arrays\" in other languages. Whereas a list associates an integer index with a set of objects:" ] }, { "cell_type": "code", "execution_count": 68, "metadata": { "collapsed": true }, "outputs": [], "source": [ "mylist = [1,2,9,21]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The index in a dictionary is called the *key*, and the corresponding dictionary entry is the *value*. A dictionary can use (almost) anything as the key. Whereas lists are formed with square brackets [], dictionaries use curly brackets {}:" ] }, { "cell_type": "code", "execution_count": 69, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Rick's age is 46\n" ] } ], "source": [ "ages = {\"Rick\": 46, \"Bob\": 86, \"Fred\": 21}\n", "print(\"Rick's age is \",ages[\"Rick\"])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "There's also a convenient way to create dictionaries without having to quote the keys." ] }, { "cell_type": "code", "execution_count": 70, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'Bob': 86, 'Fred': 20, 'Rick': 46}" ] }, "execution_count": 70, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dict(Rick=46,Bob=86,Fred=20)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The **len()** command works on both tuples and dictionaries:" ] }, { "cell_type": "code", "execution_count": 71, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "4" ] }, "execution_count": 71, "metadata": {}, "output_type": "execute_result" } ], "source": [ "len(t)" ] }, { "cell_type": "code", "execution_count": 72, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "3" ] }, "execution_count": 72, "metadata": {}, "output_type": "execute_result" } ], "source": [ "len(ages)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Conclusion of the Python Overview\n", "There is, of course, much more to the language than I've covered here. I've tried to keep this brief enough so that you can jump in and start using Python to simplify your life and work. My own experience in learning new things is that the information doesn't \"stick\" unless you try and use it for something in real life.\n", "\n", "You will no doubt need to learn more as you go. I've listed several other good references, including the [Python Tutorial](http://docs.python.org/2/tutorial/) and [Learn Python the Hard Way](http://learnpythonthehardway.org/book/). Additionally, now is a good time to start familiarizing yourself with the [Python Documentation](http://docs.python.org/2.7/), and, in particular, the [Python Language Reference](http://docs.python.org/2.7/reference/index.html).\n", "\n", "Tim Peters, one of the earliest and most prolific Python contributors, wrote the \"Zen of Python\", which can be accessed via the \"import this\" command:" ] }, { "cell_type": "code", "execution_count": 73, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The Zen of Python, by Tim Peters\n", "\n", "Beautiful is better than ugly.\n", "Explicit is better than implicit.\n", "Simple is better than complex.\n", "Complex is better than complicated.\n", "Flat is better than nested.\n", "Sparse is better than dense.\n", "Readability counts.\n", "Special cases aren't special enough to break the rules.\n", "Although practicality beats purity.\n", "Errors should never pass silently.\n", "Unless explicitly silenced.\n", "In the face of ambiguity, refuse the temptation to guess.\n", "There should be one-- and preferably only one --obvious way to do it.\n", "Although that way may not be obvious at first unless you're Dutch.\n", "Now is better than never.\n", "Although never is often better than *right* now.\n", "If the implementation is hard to explain, it's a bad idea.\n", "If the implementation is easy to explain, it may be a good idea.\n", "Namespaces are one honking great idea -- let's do more of those!\n" ] } ], "source": [ "import this" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "No matter how experienced a programmer you are, these are words to meditate on." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# II. Numpy and Scipy\n", "\n", "[Numpy](http://numpy.org) contains core routines for doing fast vector, matrix, and linear algebra-type operations in Python. [Scipy](http://scipy) contains additional routines for optimization, special functions, and so on. Both contain modules written in C and Fortran so that they're as fast as possible. Together, they give Python roughly the same capability that the [Matlab](http://www.mathworks.com/products/matlab/) program offers. (In fact, if you're an experienced Matlab user, there a [guide to Numpy for Matlab users](http://www.scipy.org/NumPy_for_Matlab_Users) just for you.)\n", "\n", "## Making vectors and matrices\n", "Fundamental to both Numpy and Scipy is the ability to work with vectors and matrices. You can create vectors from lists using the **array** command:" ] }, { "cell_type": "code", "execution_count": 74, "metadata": { "collapsed": true }, "outputs": [], "source": [ "import numpy as np\n", "import scipy as sp" ] }, { "cell_type": "code", "execution_count": 75, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([1, 2, 3, 4, 5, 6])" ] }, "execution_count": 75, "metadata": {}, "output_type": "execute_result" } ], "source": [ "array = np.array([1,2,3,4,5,6])\n", "array" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "size of the array" ] }, { "cell_type": "code", "execution_count": 76, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(6,)" ] }, "execution_count": 76, "metadata": {}, "output_type": "execute_result" } ], "source": [ "array.shape" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To build matrices, you can either use the array command with lists of lists:" ] }, { "cell_type": "code", "execution_count": 77, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[0, 1],\n", " [1, 0]])" ] }, "execution_count": 77, "metadata": {}, "output_type": "execute_result" } ], "source": [ "mat = np.array([[0,1],[1,0]])\n", "mat" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Add a column of ones to mat" ] }, { "cell_type": "code", "execution_count": 78, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[0., 1., 1.],\n", " [1., 0., 1.]])" ] }, "execution_count": 78, "metadata": {}, "output_type": "execute_result" } ], "source": [ "mat2 = np.c_[mat, np.ones(2)]\n", "mat2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "size of a matrix" ] }, { "cell_type": "code", "execution_count": 79, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(2, 3)" ] }, "execution_count": 79, "metadata": {}, "output_type": "execute_result" } ], "source": [ "mat2.shape" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can also form empty (zero) matrices of arbitrary shape (including vectors, which Numpy treats as vectors with one row), using the **zeros** command:" ] }, { "cell_type": "code", "execution_count": 80, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[0., 0., 0.],\n", " [0., 0., 0.],\n", " [0., 0., 0.]])" ] }, "execution_count": 80, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.zeros((3,3))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "There's also an **identity** command that behaves as you'd expect:" ] }, { "cell_type": "code", "execution_count": 81, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[1., 0., 0., 0.],\n", " [0., 1., 0., 0.],\n", " [0., 0., 1., 0.],\n", " [0., 0., 0., 1.]])" ] }, "execution_count": 81, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.identity(4)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "as well as a **ones** command." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Linspace, matrix functions, and plotting\n", "The **linspace** command makes a linear array of points from a starting to an ending value." ] }, { "cell_type": "code", "execution_count": 82, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([0. , 0.02040816, 0.04081633, 0.06122449, 0.08163265,\n", " 0.10204082, 0.12244898, 0.14285714, 0.16326531, 0.18367347,\n", " 0.20408163, 0.2244898 , 0.24489796, 0.26530612, 0.28571429,\n", " 0.30612245, 0.32653061, 0.34693878, 0.36734694, 0.3877551 ,\n", " 0.40816327, 0.42857143, 0.44897959, 0.46938776, 0.48979592,\n", " 0.51020408, 0.53061224, 0.55102041, 0.57142857, 0.59183673,\n", " 0.6122449 , 0.63265306, 0.65306122, 0.67346939, 0.69387755,\n", " 0.71428571, 0.73469388, 0.75510204, 0.7755102 , 0.79591837,\n", " 0.81632653, 0.83673469, 0.85714286, 0.87755102, 0.89795918,\n", " 0.91836735, 0.93877551, 0.95918367, 0.97959184, 1. ])" ] }, "execution_count": 82, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.linspace(0,1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If you provide a third argument, it takes that as the number of points in the space. If you don't provide the argument, it gives a length 50 linear space." ] }, { "cell_type": "code", "execution_count": 83, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([0. , 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1. ])" ] }, "execution_count": 83, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.linspace(0,1,11)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**linspace** is an easy way to make coordinates for plotting. Functions in the numpy library (all of which are imported into IPython notebook) can act on an entire vector (or even a matrix) of points at once. Thus," ] }, { "cell_type": "code", "execution_count": 84, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([ 0.00000000e+00, 1.27877162e-01, 2.53654584e-01, 3.75267005e-01,\n", " 4.90717552e-01, 5.98110530e-01, 6.95682551e-01, 7.81831482e-01,\n", " 8.55142763e-01, 9.14412623e-01, 9.58667853e-01, 9.87181783e-01,\n", " 9.99486216e-01, 9.95379113e-01, 9.74927912e-01, 9.38468422e-01,\n", " 8.86599306e-01, 8.20172255e-01, 7.40277997e-01, 6.48228395e-01,\n", " 5.45534901e-01, 4.33883739e-01, 3.15108218e-01, 1.91158629e-01,\n", " 6.40702200e-02, -6.40702200e-02, -1.91158629e-01, -3.15108218e-01,\n", " -4.33883739e-01, -5.45534901e-01, -6.48228395e-01, -7.40277997e-01,\n", " -8.20172255e-01, -8.86599306e-01, -9.38468422e-01, -9.74927912e-01,\n", " -9.95379113e-01, -9.99486216e-01, -9.87181783e-01, -9.58667853e-01,\n", " -9.14412623e-01, -8.55142763e-01, -7.81831482e-01, -6.95682551e-01,\n", " -5.98110530e-01, -4.90717552e-01, -3.75267005e-01, -2.53654584e-01,\n", " -1.27877162e-01, -2.44929360e-16])" ] }, "execution_count": 84, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x = np.linspace(0,2*np.pi)\n", "np.sin(x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In conjunction with **matplotlib**, this is a nice way to plot things:" ] }, { "cell_type": "code", "execution_count": 85, "metadata": { "collapsed": true }, "outputs": [], "source": [ "%matplotlib inline\n", "import matplotlib.pyplot as plt\n", "plt.style.use('ggplot')" ] }, { "cell_type": "code", "execution_count": 86, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[]" ] }, "execution_count": 86, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "plt.plot(x,np.sin(x))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Matrix operations\n", "Matrix objects act sensibly when multiplied by scalars:" ] }, { "cell_type": "code", "execution_count": 87, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[0.125, 0. , 0. ],\n", " [0. , 0.125, 0. ],\n", " [0. , 0. , 0.125]])" ] }, "execution_count": 87, "metadata": {}, "output_type": "execute_result" } ], "source": [ "0.125*np.identity(3)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "as well as when you add two matrices together. (However, the matrices have to be the same shape.)" ] }, { "cell_type": "code", "execution_count": 88, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[2., 1.],\n", " [1., 3.]])" ] }, "execution_count": 88, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.identity(2) + np.array([[1,1],[1,2]])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Something that confuses Matlab users is that the times (*) operator give element-wise multiplication rather than matrix multiplication:" ] }, { "cell_type": "code", "execution_count": 89, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[1., 0.],\n", " [0., 1.]])" ] }, "execution_count": 89, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.identity(2)*np.ones((2,2))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To get matrix multiplication, you need the **dot** command:" ] }, { "cell_type": "code", "execution_count": 90, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[1., 1.],\n", " [1., 1.]])" ] }, "execution_count": 90, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.dot(np.identity(2),np.ones((2,2)))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**dot** can also do dot products (duh!):" ] }, { "cell_type": "code", "execution_count": 91, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "5.0" ] }, "execution_count": 91, "metadata": {}, "output_type": "execute_result" } ], "source": [ "v = np.array([3,4])\n", "np.sqrt(np.dot(v,v))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "as well as matrix-vector products." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "There are **determinant**, **inverse**, and **transpose** functions that act as you would suppose. Transpose can be abbreviated with \".T\" at the end of a matrix object:" ] }, { "cell_type": "code", "execution_count": 92, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[1, 3],\n", " [2, 4]])" ] }, "execution_count": 92, "metadata": {}, "output_type": "execute_result" } ], "source": [ "m = np.array([[1,2],[3,4]])\n", "m.T" ] }, { "cell_type": "code", "execution_count": 93, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[-2. , 1. ],\n", " [ 1.5, -0.5]])" ] }, "execution_count": 93, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.linalg.inv(m)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "There's also a **diag()** function that takes a list or a vector and puts it along the diagonal of a square matrix. " ] }, { "cell_type": "code", "execution_count": 94, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[1, 0, 0, 0, 0],\n", " [0, 2, 0, 0, 0],\n", " [0, 0, 3, 0, 0],\n", " [0, 0, 0, 4, 0],\n", " [0, 0, 0, 0, 5]])" ] }, "execution_count": 94, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.diag([1,2,3,4,5])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We'll find this useful later on." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Least squares fitting\n", "Very often we deal with some data that we want to fit to some sort of expected behavior. Say we have the following:" ] }, { "cell_type": "code", "execution_count": 95, "metadata": { "collapsed": true }, "outputs": [], "source": [ "raw_data = \"\"\"\\\n", "3.1905781584582433,0.028208609537968457\n", "4.346895074946466,0.007160804747670053\n", "5.374732334047101,0.0046962988461934805\n", "8.201284796573875,0.0004614473299618756\n", "10.899357601713055,0.00005038370219939726\n", "16.295503211991434,4.377451812785309e-7\n", "21.82012847965739,3.0799922117601088e-9\n", "32.48394004282656,1.524776208284536e-13\n", "43.53319057815846,5.5012073588707224e-18\"\"\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "There's a section below on parsing CSV data. We'll steal the parser from that. For an explanation, skip ahead to that section. Otherwise, just assume that this is a way to parse that text into a numpy array that we can plot and do other analyses with." ] }, { "cell_type": "code", "execution_count": 96, "metadata": { "collapsed": true }, "outputs": [], "source": [ "data = []\n", "for line in raw_data.splitlines():\n", " words = line.split(',')\n", " data.append(words)\n", "data = np.array(data, dtype=np.float)" ] }, { "cell_type": "code", "execution_count": 97, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[3.19057816e+00, 2.82086095e-02],\n", " [4.34689507e+00, 7.16080475e-03],\n", " [5.37473233e+00, 4.69629885e-03],\n", " [8.20128480e+00, 4.61447330e-04],\n", " [1.08993576e+01, 5.03837022e-05],\n", " [1.62955032e+01, 4.37745181e-07],\n", " [2.18201285e+01, 3.07999221e-09],\n", " [3.24839400e+01, 1.52477621e-13],\n", " [4.35331906e+01, 5.50120736e-18]])" ] }, "execution_count": 97, "metadata": {}, "output_type": "execute_result" } ], "source": [ "data" ] }, { "cell_type": "code", "execution_count": 98, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([ 3.19057816, 4.34689507, 5.37473233, 8.2012848 , 10.8993576 ,\n", " 16.29550321, 21.82012848, 32.48394004, 43.53319058])" ] }, "execution_count": 98, "metadata": {}, "output_type": "execute_result" } ], "source": [ "data[:, 0]" ] }, { "cell_type": "code", "execution_count": 99, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[]" ] }, "execution_count": 99, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "plt.title(\"Raw Data\")\n", "plt.xlabel(\"Distance\")\n", "plt.plot(data[:,0],data[:,1],'bo')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Since we expect the data to have an exponential decay, we can plot it using a semi-log plot." ] }, { "cell_type": "code", "execution_count": 100, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[]" ] }, "execution_count": 100, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "plt.title(\"Raw Data\")\n", "plt.xlabel(\"Distance\")\n", "plt.semilogy(data[:,0],data[:,1],'bo')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For a pure exponential decay like this, we can fit the log of the data to a straight line. The above plot suggests this is a good approximation. Given a function\n", "$$ y = Ae^{-ax} $$\n", "$$ \\log(y) = \\log(A) - ax$$\n", "Thus, if we fit the log of the data versus x, we should get a straight line with slope $a$, and an intercept that gives the constant $A$.\n", "\n", "There's a numpy function called **polyfit** that will fit data to a polynomial form. We'll use this to fit to a straight line (a polynomial of order 1)" ] }, { "cell_type": "code", "execution_count": 101, "metadata": { "collapsed": true }, "outputs": [], "source": [ "params = sp.polyfit(data[:,0],np.log(data[:,1]),1)\n", "a = params[0]\n", "A = np.exp(params[1])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's see whether this curve fits the data." ] }, { "cell_type": "code", "execution_count": 102, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[]" ] }, "execution_count": 102, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "x = np.linspace(1,45)\n", "plt.title(\"Raw Data\")\n", "plt.xlabel(\"Distance\")\n", "plt.semilogy(data[:,0],data[:,1],'bo')\n", "plt.semilogy(x,A*np.exp(a*x),'b-')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If we have more complicated functions, we may not be able to get away with fitting to a simple polynomial. Consider the following data:" ] }, { "cell_type": "code", "execution_count": 103, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[]" ] }, "execution_count": 103, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "gauss_data = \"\"\"\\\n", "-0.9902286902286903,1.4065274110372852e-19\n", "-0.7566104566104566,2.2504438576596563e-18\n", "-0.5117810117810118,1.9459459459459454\n", "-0.31887271887271884,10.621621621621626\n", "-0.250997150997151,15.891891891891893\n", "-0.1463309463309464,23.756756756756754\n", "-0.07267267267267263,28.135135135135133\n", "-0.04426734426734419,29.02702702702703\n", "-0.0015939015939017698,29.675675675675677\n", "0.04689304689304685,29.10810810810811\n", "0.0840994840994842,27.324324324324326\n", "0.1700546700546699,22.216216216216214\n", "0.370878570878571,7.540540540540545\n", "0.5338338338338338,1.621621621621618\n", "0.722014322014322,0.08108108108108068\n", "0.9926849926849926,-0.08108108108108646\"\"\"\n", "\n", "data = []\n", "for line in gauss_data.splitlines():\n", " words = line.split(',')\n", " data.append(words)\n", "data = np.array(data, dtype=np.float)\n", "\n", "plt.plot(data[:,0],data[:,1],'bo')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This data looks more Gaussian than exponential. If we wanted to, we could use **polyfit** for this as well, but let's use the **curve_fit** function from Scipy, which can fit to arbitrary functions. You can learn more using help(curve_fit).\n", "\n", "First define a general Gaussian function to fit to." ] }, { "cell_type": "code", "execution_count": 104, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def gauss(x,A,a): \n", " return A*np.exp(a*x**2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now fit to it using **curve_fit**:" ] }, { "cell_type": "code", "execution_count": 105, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[]" ] }, "execution_count": 105, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "from scipy.optimize import curve_fit\n", "\n", "params,conv = curve_fit(gauss,data[:,0],data[:,1])\n", "x = np.linspace(-1,1)\n", "plt.plot(data[:,0],data[:,1],'bo')\n", "A,a = params\n", "plt.plot(x,gauss(x,A,a),'b-')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The **curve_fit** routine we just used is built on top of a very good general **minimization** capability in Scipy. You can learn more [at the scipy documentation pages](http://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.minimize.html)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Monte Carlo and random numbers\n", "Many methods in scientific computing rely on Monte Carlo integration, where a sequence of (pseudo) random numbers are used to approximate the integral of a function. Python has good random number generators in the standard library. The **random()** function gives pseudorandom numbers uniformly distributed between 0 and 1:" ] }, { "cell_type": "code", "execution_count": 106, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[]" ] }, "execution_count": 106, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "from random import random\n", "rands = []\n", "for i in range(100):\n", " rands.append(random())\n", "plt.plot(rands)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**random()** uses the [Mersenne Twister](http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html) algorithm, which is a highly regarded pseudorandom number generator. There are also functions to generate random integers, to randomly shuffle a list, and functions to pick random numbers from a particular distribution, like the normal distribution:" ] }, { "cell_type": "code", "execution_count": 107, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[]" ] }, "execution_count": 107, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "from random import gauss\n", "grands = []\n", "for i in range(100):\n", " grands.append(gauss(0,1))\n", "plt.plot(grands)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "It is generally more efficient to generate a list of random numbers all at once, particularly if you're drawing from a non-uniform distribution. Numpy has functions to generate vectors and matrices of particular types of random distributions." ] }, { "cell_type": "code", "execution_count": 108, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[]" ] }, "execution_count": 108, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "plt.plot(np.random.rand(100))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# III. Introduction to Pandas" ] }, { "cell_type": "code", "execution_count": 109, "metadata": { "collapsed": true }, "outputs": [], "source": [ "import pandas as pd\n", "import numpy as np" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Series\n", "\n", "A Series is a one-dimensional array-like object containing an array of data and an associated array of data labels. The data can be any NumPy data type and the labels are the Series' index." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Create a Series:" ] }, { "cell_type": "code", "execution_count": 110, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0 1\n", "1 1\n", "2 2\n", "3 -3\n", "4 -5\n", "5 8\n", "6 13\n", "dtype: int64" ] }, "execution_count": 110, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ser_1 = pd.Series([1, 1, 2, -3, -5, 8, 13])\n", "ser_1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Get the array representation of a Series:" ] }, { "cell_type": "code", "execution_count": 111, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([ 1, 1, 2, -3, -5, 8, 13])" ] }, "execution_count": 111, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ser_1.values" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Index objects are immutable and hold the axis labels and metadata such as names and axis names.\n", "\n", "Get the index of the Series:" ] }, { "cell_type": "code", "execution_count": 112, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "RangeIndex(start=0, stop=7, step=1)" ] }, "execution_count": 112, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ser_1.index" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Create a Series with a custom index:" ] }, { "cell_type": "code", "execution_count": 113, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "a 1\n", "b 1\n", "c 2\n", "d -3\n", "e -5\n", "dtype: int64" ] }, "execution_count": 113, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ser_2 = pd.Series([1, 1, 2, -3, -5], index=['a', 'b', 'c', 'd', 'e'])\n", "ser_2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Get a value from a Series:" ] }, { "cell_type": "code", "execution_count": 114, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 114, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ser_2[4] == ser_2['e']" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Get a set of values from a Series by passing in a list:" ] }, { "cell_type": "code", "execution_count": 115, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "c 2\n", "a 1\n", "b 1\n", "dtype: int64" ] }, "execution_count": 115, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ser_2[['c', 'a', 'b']]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Get values great than 0:" ] }, { "cell_type": "code", "execution_count": 116, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "a 1\n", "b 1\n", "c 2\n", "dtype: int64" ] }, "execution_count": 116, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ser_2[ser_2 > 0]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Scalar multiply:" ] }, { "cell_type": "code", "execution_count": 117, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "a 2\n", "b 2\n", "c 4\n", "d -6\n", "e -10\n", "dtype: int64" ] }, "execution_count": 117, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ser_2 * 2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Apply a numpy math function:" ] }, { "cell_type": "code", "execution_count": 118, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "a 2.718282\n", "b 2.718282\n", "c 7.389056\n", "d 0.049787\n", "e 0.006738\n", "dtype: float64" ] }, "execution_count": 118, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.exp(ser_2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A Series is like a fixed-length, ordered dict. \n", "\n", "Create a series by passing in a dict:" ] }, { "cell_type": "code", "execution_count": 119, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "bar 200\n", "baz 300\n", "foo 100\n", "dtype: int64" ] }, "execution_count": 119, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dict_1 = {'foo' : 100, 'bar' : 200, 'baz' : 300}\n", "ser_3 = pd.Series(dict_1)\n", "ser_3" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Re-order a Series by passing in an index (indices not found are NaN):" ] }, { "cell_type": "code", "execution_count": 120, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "foo 100.0\n", "bar 200.0\n", "baz 300.0\n", "qux NaN\n", "dtype: float64" ] }, "execution_count": 120, "metadata": {}, "output_type": "execute_result" } ], "source": [ "index = ['foo', 'bar', 'baz', 'qux']\n", "ser_4 = pd.Series(dict_1, index=index)\n", "ser_4" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Check for NaN with the pandas method:" ] }, { "cell_type": "code", "execution_count": 121, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "foo False\n", "bar False\n", "baz False\n", "qux True\n", "dtype: bool" ] }, "execution_count": 121, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pd.isnull(ser_4)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Check for NaN with the Series method:" ] }, { "cell_type": "code", "execution_count": 122, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "foo False\n", "bar False\n", "baz False\n", "qux True\n", "dtype: bool" ] }, "execution_count": 122, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ser_4.isnull()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Series automatically aligns differently indexed data in arithmetic operations:" ] }, { "cell_type": "code", "execution_count": 123, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "bar 400.0\n", "baz 600.0\n", "foo 200.0\n", "qux NaN\n", "dtype: float64" ] }, "execution_count": 123, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ser_3 + ser_4" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Name a Series:" ] }, { "cell_type": "code", "execution_count": 124, "metadata": { "collapsed": true }, "outputs": [], "source": [ "ser_4.name = 'foobarbazqux'" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Name a Series index:" ] }, { "cell_type": "code", "execution_count": 125, "metadata": { "collapsed": true }, "outputs": [], "source": [ "ser_4.index.name = 'label'" ] }, { "cell_type": "code", "execution_count": 126, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "label\n", "foo 100.0\n", "bar 200.0\n", "baz 300.0\n", "qux NaN\n", "Name: foobarbazqux, dtype: float64" ] }, "execution_count": 126, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ser_4" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Rename a Series' index in place:" ] }, { "cell_type": "code", "execution_count": 127, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "fo 100.0\n", "br 200.0\n", "bz 300.0\n", "qx NaN\n", "Name: foobarbazqux, dtype: float64" ] }, "execution_count": 127, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ser_4.index = ['fo', 'br', 'bz', 'qx']\n", "ser_4" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## DataFrame\n", "\n", "A DataFrame is a tabular data structure containing an ordered collection of columns. Each column can have a different type. DataFrames have both row and column indices and is analogous to a dict of Series. Row and column operations are treated roughly symmetrically. Columns returned when indexing a DataFrame are views of the underlying data, not a copy. To obtain a copy, use the Series' copy method.\n", "\n", "Create a DataFrame:" ] }, { "cell_type": "code", "execution_count": 128, "metadata": {}, "outputs": [ { "data": { "text/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", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
popstateyear
05.0VA2012
15.1VA2013
25.2VA2014
34.0MD2014
44.1MD2015
\n", "
" ], "text/plain": [ " pop state year\n", "0 5.0 VA 2012\n", "1 5.1 VA 2013\n", "2 5.2 VA 2014\n", "3 4.0 MD 2014\n", "4 4.1 MD 2015" ] }, "execution_count": 128, "metadata": {}, "output_type": "execute_result" } ], "source": [ "data_1 = {'state' : ['VA', 'VA', 'VA', 'MD', 'MD'],\n", " 'year' : [2012, 2013, 2014, 2014, 2015],\n", " 'pop' : [5.0, 5.1, 5.2, 4.0, 4.1]}\n", "df_1 = pd.DataFrame(data_1)\n", "df_1" ] }, { "cell_type": "code", "execution_count": 129, "metadata": {}, "outputs": [ { "data": { "text/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", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
yearstatepop
02012VA5.0
12013VA5.1
22014VA5.2
32014MD4.0
42015MD4.1
\n", "
" ], "text/plain": [ " year state pop\n", "0 2012 VA 5.0\n", "1 2013 VA 5.1\n", "2 2014 VA 5.2\n", "3 2014 MD 4.0\n", "4 2015 MD 4.1" ] }, "execution_count": 129, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_2 = pd.DataFrame(data_1, columns=['year', 'state', 'pop'])\n", "df_2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Like Series, columns that are not present in the data are NaN:" ] }, { "cell_type": "code", "execution_count": 130, "metadata": {}, "outputs": [ { "data": { "text/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", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
yearstatepopunempl
02012VA5.0NaN
12013VA5.1NaN
22014VA5.2NaN
32014MD4.0NaN
42015MD4.1NaN
\n", "
" ], "text/plain": [ " year state pop unempl\n", "0 2012 VA 5.0 NaN\n", "1 2013 VA 5.1 NaN\n", "2 2014 VA 5.2 NaN\n", "3 2014 MD 4.0 NaN\n", "4 2015 MD 4.1 NaN" ] }, "execution_count": 130, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_3 = pd.DataFrame(data_1, columns=['year', 'state', 'pop', 'unempl'])\n", "df_3" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Retrieve a column by key, returning a Series:" ] }, { "cell_type": "code", "execution_count": 131, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0 VA\n", "1 VA\n", "2 VA\n", "3 MD\n", "4 MD\n", "Name: state, dtype: object" ] }, "execution_count": 131, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_3['state']" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Retrive a column by attribute, returning a Series:" ] }, { "cell_type": "code", "execution_count": 132, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0 2012\n", "1 2013\n", "2 2014\n", "3 2014\n", "4 2015\n", "Name: year, dtype: int64" ] }, "execution_count": 132, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_3.year" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Retrieve a row by position:" ] }, { "cell_type": "code", "execution_count": 133, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "year 2012\n", "state VA\n", "pop 5\n", "unempl NaN\n", "Name: 0, dtype: object" ] }, "execution_count": 133, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_3.iloc[0]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Update a column by assignment:" ] }, { "cell_type": "code", "execution_count": 134, "metadata": {}, "outputs": [ { "data": { "text/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", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
yearstatepopunempl
02012VA5.00
12013VA5.11
22014VA5.22
32014MD4.03
42015MD4.14
\n", "
" ], "text/plain": [ " year state pop unempl\n", "0 2012 VA 5.0 0\n", "1 2013 VA 5.1 1\n", "2 2014 VA 5.2 2\n", "3 2014 MD 4.0 3\n", "4 2015 MD 4.1 4" ] }, "execution_count": 134, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_3['unempl'] = np.arange(5)\n", "df_3" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Assign a Series to a column (note if assigning a list or array, the length must match the DataFrame, unlike a Series):" ] }, { "cell_type": "code", "execution_count": 135, "metadata": {}, "outputs": [ { "data": { "text/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", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
yearstatepopunempl
02012VA5.0NaN
12013VA5.1NaN
22014VA5.26.0
32014MD4.06.0
42015MD4.16.1
\n", "
" ], "text/plain": [ " year state pop unempl\n", "0 2012 VA 5.0 NaN\n", "1 2013 VA 5.1 NaN\n", "2 2014 VA 5.2 6.0\n", "3 2014 MD 4.0 6.0\n", "4 2015 MD 4.1 6.1" ] }, "execution_count": 135, "metadata": {}, "output_type": "execute_result" } ], "source": [ "unempl = pd.Series([6.0, 6.0, 6.1], index=[2, 3, 4])\n", "df_3['unempl'] = unempl\n", "df_3" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Assign a new column that doesn't exist to create a new column:" ] }, { "cell_type": "code", "execution_count": 136, "metadata": {}, "outputs": [ { "data": { "text/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", " \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", " \n", " \n", " \n", "
yearstatepopunemplstate_dup
02012VA5.0NaNVA
12013VA5.1NaNVA
22014VA5.26.0VA
32014MD4.06.0MD
42015MD4.16.1MD
\n", "
" ], "text/plain": [ " year state pop unempl state_dup\n", "0 2012 VA 5.0 NaN VA\n", "1 2013 VA 5.1 NaN VA\n", "2 2014 VA 5.2 6.0 VA\n", "3 2014 MD 4.0 6.0 MD\n", "4 2015 MD 4.1 6.1 MD" ] }, "execution_count": 136, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_3['state_dup'] = df_3['state']\n", "df_3" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Delete a column:" ] }, { "cell_type": "code", "execution_count": 137, "metadata": {}, "outputs": [ { "data": { "text/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", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
yearstatepopunempl
02012VA5.0NaN
12013VA5.1NaN
22014VA5.26.0
32014MD4.06.0
42015MD4.16.1
\n", "
" ], "text/plain": [ " year state pop unempl\n", "0 2012 VA 5.0 NaN\n", "1 2013 VA 5.1 NaN\n", "2 2014 VA 5.2 6.0\n", "3 2014 MD 4.0 6.0\n", "4 2015 MD 4.1 6.1" ] }, "execution_count": 137, "metadata": {}, "output_type": "execute_result" } ], "source": [ "del df_3['state_dup']\n", "df_3" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Transpose the DataFrame:" ] }, { "cell_type": "code", "execution_count": 138, "metadata": {}, "outputs": [ { "data": { "text/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", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
01234
year20122013201420142015
stateVAVAVAMDMD
pop55.15.244.1
unemplNaNNaN666.1
\n", "
" ], "text/plain": [ " 0 1 2 3 4\n", "year 2012 2013 2014 2014 2015\n", "state VA VA VA MD MD\n", "pop 5 5.1 5.2 4 4.1\n", "unempl NaN NaN 6 6 6.1" ] }, "execution_count": 138, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_3.T" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Create a DataFrame from a nested dict of dicts (the keys in the inner dicts are unioned and sorted to form the index in the result, unless an explicit index is specified):" ] }, { "cell_type": "code", "execution_count": 139, "metadata": {}, "outputs": [ { "data": { "text/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", " \n", "
MDVA
2013NaN5.1
20144.05.2
20154.1NaN
\n", "
" ], "text/plain": [ " MD VA\n", "2013 NaN 5.1\n", "2014 4.0 5.2\n", "2015 4.1 NaN" ] }, "execution_count": 139, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pop = {'VA' : {2013 : 5.1, 2014 : 5.2},\n", " 'MD' : {2014 : 4.0, 2015 : 4.1}}\n", "df_4 = pd.DataFrame(pop)\n", "df_4" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Create a DataFrame from a dict of Series:" ] }, { "cell_type": "code", "execution_count": 140, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
MDVA
2014NaN5.2
20154.1NaN
\n", "
" ], "text/plain": [ " MD VA\n", "2014 NaN 5.2\n", "2015 4.1 NaN" ] }, "execution_count": 140, "metadata": {}, "output_type": "execute_result" } ], "source": [ "data_2 = {'VA' : df_4['VA'][1:],\n", " 'MD' : df_4['MD'][2:]}\n", "df_5 = pd.DataFrame(data_2)\n", "df_5" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Set the DataFrame index name:" ] }, { "cell_type": "code", "execution_count": 141, "metadata": {}, "outputs": [ { "data": { "text/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", " \n", "
MDVA
year
2014NaN5.2
20154.1NaN
\n", "
" ], "text/plain": [ " MD VA\n", "year \n", "2014 NaN 5.2\n", "2015 4.1 NaN" ] }, "execution_count": 141, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_5.index.name = 'year'\n", "df_5" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Set the DataFrame columns name:" ] }, { "cell_type": "code", "execution_count": 142, "metadata": {}, "outputs": [ { "data": { "text/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", " \n", "
stateMDVA
year
2014NaN5.2
20154.1NaN
\n", "
" ], "text/plain": [ "state MD VA\n", "year \n", "2014 NaN 5.2\n", "2015 4.1 NaN" ] }, "execution_count": 142, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_5.columns.name = 'state'\n", "df_5" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Return the data contained in a DataFrame as a 2D ndarray:" ] }, { "cell_type": "code", "execution_count": 143, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[nan, 5.2],\n", " [4.1, nan]])" ] }, "execution_count": 143, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_5.values" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If the columns are different dtypes, the 2D ndarray's dtype will accomodate all of the columns:" ] }, { "cell_type": "code", "execution_count": 144, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[2012, 'VA', 5.0, nan],\n", " [2013, 'VA', 5.1, nan],\n", " [2014, 'VA', 5.2, 6.0],\n", " [2014, 'MD', 4.0, 6.0],\n", " [2015, 'MD', 4.1, 6.1]], dtype=object)" ] }, "execution_count": 144, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_3.values" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Reindexing" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Create a new object with the data conformed to a new index. Any missing values are set to NaN." ] }, { "cell_type": "code", "execution_count": 145, "metadata": {}, "outputs": [ { "data": { "text/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", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
yearstatepopunempl
02012VA5.0NaN
12013VA5.1NaN
22014VA5.26.0
32014MD4.06.0
42015MD4.16.1
\n", "
" ], "text/plain": [ " year state pop unempl\n", "0 2012 VA 5.0 NaN\n", "1 2013 VA 5.1 NaN\n", "2 2014 VA 5.2 6.0\n", "3 2014 MD 4.0 6.0\n", "4 2015 MD 4.1 6.1" ] }, "execution_count": 145, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_3" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Reindexing rows returns a new frame with the specified index:" ] }, { "cell_type": "code", "execution_count": 146, "metadata": {}, "outputs": [ { "data": { "text/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", " \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", " \n", " \n", " \n", " \n", "
yearstatepopunempl
5NaNNaNNaNNaN
42015.0MD4.16.1
32014.0MD4.06.0
22014.0VA5.26.0
12013.0VA5.1NaN
02012.0VA5.0NaN
\n", "
" ], "text/plain": [ " year state pop unempl\n", "5 NaN NaN NaN NaN\n", "4 2015.0 MD 4.1 6.1\n", "3 2014.0 MD 4.0 6.0\n", "2 2014.0 VA 5.2 6.0\n", "1 2013.0 VA 5.1 NaN\n", "0 2012.0 VA 5.0 NaN" ] }, "execution_count": 146, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_3.reindex(list(reversed(range(0, 6))))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Reindex columns:" ] }, { "cell_type": "code", "execution_count": 147, "metadata": {}, "outputs": [ { "data": { "text/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", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
statepopunemplyear
0VA5.0NaN2012
1VA5.1NaN2013
2VA5.26.02014
3MD4.06.02014
4MD4.16.12015
\n", "
" ], "text/plain": [ " state pop unempl year\n", "0 VA 5.0 NaN 2012\n", "1 VA 5.1 NaN 2013\n", "2 VA 5.2 6.0 2014\n", "3 MD 4.0 6.0 2014\n", "4 MD 4.1 6.1 2015" ] }, "execution_count": 147, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_3.reindex(columns=['state', 'pop', 'unempl', 'year'])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Dropping Entries" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Drop rows from a Series or DataFrame:" ] }, { "cell_type": "code", "execution_count": 148, "metadata": {}, "outputs": [ { "data": { "text/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", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
yearstatepopunempl
22014VA5.26.0
32014MD4.06.0
42015MD4.16.1
\n", "
" ], "text/plain": [ " year state pop unempl\n", "2 2014 VA 5.2 6.0\n", "3 2014 MD 4.0 6.0\n", "4 2015 MD 4.1 6.1" ] }, "execution_count": 148, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_7 = df_3.drop([0, 1])\n", "df_7" ] }, { "cell_type": "code", "execution_count": 149, "metadata": {}, "outputs": [ { "data": { "text/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", " \n", " \n", " \n", " \n", " \n", "
yearstatepop
22014VA5.2
32014MD4.0
42015MD4.1
\n", "
" ], "text/plain": [ " year state pop\n", "2 2014 VA 5.2\n", "3 2014 MD 4.0\n", "4 2015 MD 4.1" ] }, "execution_count": 149, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_7 = df_7.drop('unempl', axis=1)\n", "df_7" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Indexing, Selecting, Filtering" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Pandas supports indexing into a DataFrame." ] }, { "cell_type": "code", "execution_count": 150, "metadata": {}, "outputs": [ { "data": { "text/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", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
yearstatepopunempl
02012VA5.0NaN
12013VA5.1NaN
22014VA5.26.0
32014MD4.06.0
42015MD4.16.1
\n", "
" ], "text/plain": [ " year state pop unempl\n", "0 2012 VA 5.0 NaN\n", "1 2013 VA 5.1 NaN\n", "2 2014 VA 5.2 6.0\n", "3 2014 MD 4.0 6.0\n", "4 2015 MD 4.1 6.1" ] }, "execution_count": 150, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_3" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Select specified columns from a DataFrame:" ] }, { "cell_type": "code", "execution_count": 151, "metadata": {}, "outputs": [ { "data": { "text/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", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
popunempl
05.0NaN
15.1NaN
25.26.0
34.06.0
44.16.1
\n", "
" ], "text/plain": [ " pop unempl\n", "0 5.0 NaN\n", "1 5.1 NaN\n", "2 5.2 6.0\n", "3 4.0 6.0\n", "4 4.1 6.1" ] }, "execution_count": 151, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_3[['pop', 'unempl']]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Select a slice from a DataFrame:" ] }, { "cell_type": "code", "execution_count": 152, "metadata": {}, "outputs": [ { "data": { "text/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", " \n", " \n", "
yearstatepopunempl
02012VA5.0NaN
12013VA5.1NaN
\n", "
" ], "text/plain": [ " year state pop unempl\n", "0 2012 VA 5.0 NaN\n", "1 2013 VA 5.1 NaN" ] }, "execution_count": 152, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_3[:2]" ] }, { "cell_type": "code", "execution_count": 153, "metadata": {}, "outputs": [ { "data": { "text/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", " \n", " \n", "
yearstatepopunempl
12013VA5.1NaN
22014VA5.26.0
\n", "
" ], "text/plain": [ " year state pop unempl\n", "1 2013 VA 5.1 NaN\n", "2 2014 VA 5.2 6.0" ] }, "execution_count": 153, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_3.iloc[1:3]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Select from a DataFrame based on a filter:" ] }, { "cell_type": "code", "execution_count": 154, "metadata": {}, "outputs": [ { "data": { "text/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", " \n", " \n", "
yearstatepopunempl
12013VA5.1NaN
22014VA5.26.0
\n", "
" ], "text/plain": [ " year state pop unempl\n", "1 2013 VA 5.1 NaN\n", "2 2014 VA 5.2 6.0" ] }, "execution_count": 154, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_3[df_3['pop'] > 5]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Select a slice of rows from a specific column of a DataFrame:" ] }, { "cell_type": "code", "execution_count": 155, "metadata": {}, "outputs": [ { "data": { "text/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", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
yearstatepopunempl
02012VA5.0NaN
12013VA5.1NaN
22014VA5.26.0
32014MD4.06.0
42015MD4.16.1
\n", "
" ], "text/plain": [ " year state pop unempl\n", "0 2012 VA 5.0 NaN\n", "1 2013 VA 5.1 NaN\n", "2 2014 VA 5.2 6.0\n", "3 2014 MD 4.0 6.0\n", "4 2015 MD 4.1 6.1" ] }, "execution_count": 155, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_3.loc[0:2, 'pop']\n", "df_3" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Arithmetic and Data Alignment" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Adding DataFrame objects results in the union of index pairs for rows and columns if the pairs are not the same, resulting in NaN for indices that do not overlap:" ] }, { "cell_type": "code", "execution_count": 156, "metadata": {}, "outputs": [ { "data": { "text/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", " \n", " \n", " \n", " \n", " \n", "
abc
00.5488140.7151890.602763
10.5448830.4236550.645894
20.4375870.8917730.963663
\n", "
" ], "text/plain": [ " a b c\n", "0 0.548814 0.715189 0.602763\n", "1 0.544883 0.423655 0.645894\n", "2 0.437587 0.891773 0.963663" ] }, "execution_count": 156, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.random.seed(0)\n", "df_8 = pd.DataFrame(np.random.rand(9).reshape((3, 3)),\n", " columns=['a', 'b', 'c'])\n", "df_8" ] }, { "cell_type": "code", "execution_count": 157, "metadata": {}, "outputs": [ { "data": { "text/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", " \n", " \n", " \n", " \n", " \n", "
bcd
00.4170220.7203240.000114
10.3023330.1467560.092339
20.1862600.3455610.396767
\n", "
" ], "text/plain": [ " b c d\n", "0 0.417022 0.720324 0.000114\n", "1 0.302333 0.146756 0.092339\n", "2 0.186260 0.345561 0.396767" ] }, "execution_count": 157, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.random.seed(1)\n", "df_9 = pd.DataFrame(np.random.rand(9).reshape((3, 3)),\n", " columns=['b', 'c', 'd'])\n", "df_9" ] }, { "cell_type": "code", "execution_count": 158, "metadata": {}, "outputs": [ { "data": { "text/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", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
abcd
0NaN1.1322111.323088NaN
1NaN0.7259870.792650NaN
2NaN1.0780331.309223NaN
\n", "
" ], "text/plain": [ " a b c d\n", "0 NaN 1.132211 1.323088 NaN\n", "1 NaN 0.725987 0.792650 NaN\n", "2 NaN 1.078033 1.309223 NaN" ] }, "execution_count": 158, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_8 + df_9" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Set a fill value instead of NaN for indices that do not overlap:" ] }, { "cell_type": "code", "execution_count": 159, "metadata": {}, "outputs": [ { "data": { "text/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", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
abcd
00.5488141.1322111.3230880.000114
10.5448830.7259870.7926500.092339
20.4375871.0780331.3092230.396767
\n", "
" ], "text/plain": [ " a b c d\n", "0 0.548814 1.132211 1.323088 0.000114\n", "1 0.544883 0.725987 0.792650 0.092339\n", "2 0.437587 1.078033 1.309223 0.396767" ] }, "execution_count": 159, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_10 = df_8.add(df_9, fill_value=0)\n", "df_10" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Like NumPy, pandas supports arithmetic operations between DataFrames and Series.\n", "\n", "Match the index of the Series on the DataFrame's columns, broadcasting down the rows:" ] }, { "cell_type": "code", "execution_count": 160, "metadata": {}, "outputs": [ { "data": { "text/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", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
abcd
00.0000000.0000000.0000000.000000
1-0.003930-0.406224-0.5304380.092224
2-0.111226-0.054178-0.0138640.396653
\n", "
" ], "text/plain": [ " a b c d\n", "0 0.000000 0.000000 0.000000 0.000000\n", "1 -0.003930 -0.406224 -0.530438 0.092224\n", "2 -0.111226 -0.054178 -0.013864 0.396653" ] }, "execution_count": 160, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ser_8 = df_10.iloc[0]\n", "df_11 = df_10 - ser_8\n", "df_11" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Match the index of the Series on the DataFrame's columns, broadcasting down the rows and union the indices that do not match:" ] }, { "cell_type": "code", "execution_count": 161, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "a 0\n", "d 1\n", "e 2\n", "dtype: int64" ] }, "execution_count": 161, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ser_9 = pd.Series(range(3), index=['a', 'd', 'e'])\n", "ser_9" ] }, { "cell_type": "code", "execution_count": 162, "metadata": {}, "outputs": [ { "data": { "text/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", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
abcde
00.000000NaNNaN-1.000000NaN
1-0.003930NaNNaN-0.907776NaN
2-0.111226NaNNaN-0.603347NaN
\n", "
" ], "text/plain": [ " a b c d e\n", "0 0.000000 NaN NaN -1.000000 NaN\n", "1 -0.003930 NaN NaN -0.907776 NaN\n", "2 -0.111226 NaN NaN -0.603347 NaN" ] }, "execution_count": 162, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_11 - ser_9" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Function Application and Mapping" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "NumPy ufuncs (element-wise array methods) operate on pandas objects:" ] }, { "cell_type": "code", "execution_count": 163, "metadata": {}, "outputs": [ { "data": { "text/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", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
abcd
00.0000000.0000000.0000000.000000
10.0039300.4062240.5304380.092224
20.1112260.0541780.0138640.396653
\n", "
" ], "text/plain": [ " a b c d\n", "0 0.000000 0.000000 0.000000 0.000000\n", "1 0.003930 0.406224 0.530438 0.092224\n", "2 0.111226 0.054178 0.013864 0.396653" ] }, "execution_count": 163, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_11 = np.abs(df_11)\n", "df_11" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Apply a function on 1D arrays to each column:" ] }, { "cell_type": "code", "execution_count": 164, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "a 0.115157\n", "b 0.460402\n", "c 0.544302\n", "d 0.488877\n", "dtype: float64" ] }, "execution_count": 164, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_11.apply(sum)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Apply a function on 1D arrays to each row:" ] }, { "cell_type": "code", "execution_count": 165, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0 0.000000\n", "1 1.032816\n", "2 0.575922\n", "dtype: float64" ] }, "execution_count": 165, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_11.apply(sum, axis=1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Apply an element-wise Python function to a DataFrame:" ] }, { "cell_type": "code", "execution_count": 166, "metadata": {}, "outputs": [ { "data": { "text/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", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
abcd
00.000.000.000.00
10.000.410.530.09
20.110.050.010.40
\n", "
" ], "text/plain": [ " a b c d\n", "0 0.00 0.00 0.00 0.00\n", "1 0.00 0.41 0.53 0.09\n", "2 0.11 0.05 0.01 0.40" ] }, "execution_count": 166, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def func_3(x): \n", " return '%.2f' %x\n", "df_11.applymap(func_3)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Sorting" ] }, { "cell_type": "code", "execution_count": 167, "metadata": {}, "outputs": [ { "data": { "text/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", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
cabd
three0123
one4567
two891011
\n", "
" ], "text/plain": [ " c a b d\n", "three 0 1 2 3\n", "one 4 5 6 7\n", "two 8 9 10 11" ] }, "execution_count": 167, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_12 = pd.DataFrame(np.arange(12).reshape((3, 4)),\n", " index=['three', 'one', 'two'],\n", " columns=['c', 'a', 'b', 'd'])\n", "df_12" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Sort a DataFrame by its index:" ] }, { "cell_type": "code", "execution_count": 168, "metadata": {}, "outputs": [ { "data": { "text/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", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
cabd
one4567
three0123
two891011
\n", "
" ], "text/plain": [ " c a b d\n", "one 4 5 6 7\n", "three 0 1 2 3\n", "two 8 9 10 11" ] }, "execution_count": 168, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_12.sort_index()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Sort a DataFrame by columns in descending order:" ] }, { "cell_type": "code", "execution_count": 169, "metadata": {}, "outputs": [ { "data": { "text/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", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
dcba
three3021
one7465
two118109
\n", "
" ], "text/plain": [ " d c b a\n", "three 3 0 2 1\n", "one 7 4 6 5\n", "two 11 8 10 9" ] }, "execution_count": 169, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_12.sort_index(axis=1, ascending=False)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Sort a DataFrame's values by column:" ] }, { "cell_type": "code", "execution_count": 170, "metadata": {}, "outputs": [ { "data": { "text/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", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
cabd
three0123
one4567
two891011
\n", "
" ], "text/plain": [ " c a b d\n", "three 0 1 2 3\n", "one 4 5 6 7\n", "two 8 9 10 11" ] }, "execution_count": 170, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_12.sort_values(by=['d', 'c'])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Summarizing and Computing Descriptive Statistics" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Unlike NumPy arrays, Pandas descriptive statistics automatically exclude missing data. NaN values are excluded unless the entire row or column is NA." ] }, { "cell_type": "code", "execution_count": 171, "metadata": {}, "outputs": [ { "data": { "text/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", " \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", " \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", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
abccat1cat2
0-2.3634691.135345-1.0170140.01.0
10.637362-0.8599071.7726082.01.0
2-1.1103630.1812140.5643450.01.0
3-0.5665100.7299760.3729942.01.0
40.533811-0.0919731.9138202.01.0
50.3307971.141943-1.1295950.01.0
6-0.8500520.960820-0.2174181.00.0
70.1585150.873418-0.1113832.00.0
8-1.038039-1.009480-1.0582571.01.0
90.656284-0.062492-1.7386540.00.0
\n", "
" ], "text/plain": [ " a b c cat1 cat2\n", "0 -2.363469 1.135345 -1.017014 0.0 1.0\n", "1 0.637362 -0.859907 1.772608 2.0 1.0\n", "2 -1.110363 0.181214 0.564345 0.0 1.0\n", "3 -0.566510 0.729976 0.372994 2.0 1.0\n", "4 0.533811 -0.091973 1.913820 2.0 1.0\n", "5 0.330797 1.141943 -1.129595 0.0 1.0\n", "6 -0.850052 0.960820 -0.217418 1.0 0.0\n", "7 0.158515 0.873418 -0.111383 2.0 0.0\n", "8 -1.038039 -1.009480 -1.058257 1.0 1.0\n", "9 0.656284 -0.062492 -1.738654 0.0 0.0" ] }, "execution_count": 171, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_15 = pd.DataFrame(np.random.randn(10, 3),\n", " columns=['a', 'b', 'c'])\n", "df_15['cat1'] = (np.random.rand(10) * 3).round(0)\n", "df_15['cat2'] = (np.random.rand(10)).round(0)\n", "df_15" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Sum and Mean" ] }, { "cell_type": "code", "execution_count": 172, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "a -3.611664\n", "b 2.998865\n", "c -0.648555\n", "cat1 10.000000\n", "cat2 7.000000\n", "dtype: float64" ] }, "execution_count": 172, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_15.sum()" ] }, { "cell_type": "code", "execution_count": 173, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0 -1.245137\n", "1 4.550063\n", "2 0.635196\n", "3 3.536459\n", "4 5.355658\n", "5 1.343144\n", "6 0.893349\n", "7 2.920550\n", "8 -1.105775\n", "9 -1.144862\n", "dtype: float64" ] }, "execution_count": 173, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_15.sum(axis=1)" ] }, { "cell_type": "code", "execution_count": 174, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "a -0.361166\n", "b 0.299886\n", "c -0.064856\n", "cat1 1.000000\n", "cat2 0.700000\n", "dtype: float64" ] }, "execution_count": 174, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_15.mean(axis=0)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Descriptive analysis" ] }, { "cell_type": "code", "execution_count": 175, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "count 10.000000\n", "mean -0.361166\n", "std 0.993980\n", "min -2.363469\n", "25% -0.991042\n", "50% -0.203998\n", "75% 0.483057\n", "max 0.656284\n", "Name: a, dtype: float64" ] }, "execution_count": 175, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_15['a'].describe()" ] }, { "cell_type": "code", "execution_count": 176, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "2.0 4\n", "0.0 4\n", "1.0 2\n", "Name: cat1, dtype: int64" ] }, "execution_count": 176, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_15['cat1'].value_counts()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Pivot tables" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### group by cat1 and calculate mean" ] }, { "cell_type": "code", "execution_count": 177, "metadata": {}, "outputs": [ { "data": { "text/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", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
abccat2
cat1
0.0-0.6216880.599003-0.8302300.75
1.0-0.944046-0.024330-0.6378370.50
2.00.1907940.1628780.9870100.75
\n", "
" ], "text/plain": [ " a b c cat2\n", "cat1 \n", "0.0 -0.621688 0.599003 -0.830230 0.75\n", "1.0 -0.944046 -0.024330 -0.637837 0.50\n", "2.0 0.190794 0.162878 0.987010 0.75" ] }, "execution_count": 177, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pd.pivot_table(df_15, index='cat1', aggfunc=np.mean)" ] } ], "metadata": { "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.6.4" } }, "nbformat": 4, "nbformat_minor": 2 }