{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Tools - pandas**\n",
    "\n",
    "*The `pandas` library provides high-performance, easy-to-use data structures and data analysis tools. The main data structure is the `DataFrame`, which you can think of as an in-memory 2D table (like a spreadsheet, with column names and row labels). Many features available in Excel are available programmatically, such as creating pivot tables, computing columns based on other columns, plotting graphs, etc. You can also group rows by column value, or join tables much like in SQL. Pandas is also great at handling time series.*\n",
    "\n",
    "Prerequisites:\n",
    "* NumPy – if you are not familiar with NumPy, we recommend that you go through the [NumPy tutorial](tools_numpy.ipynb) now."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Setup\n",
    "First, let's make sure this notebook works well in both python 2 and 3:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from __future__ import division, print_function, unicode_literals"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now let's import `pandas`. People usually import it as `pd`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import pandas as pd"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# `Series` objects\n",
    "The `pandas` library contains these useful data structures:\n",
    "* `Series` objects, that we will discuss now. A `Series` object is 1D array, similar to a column in a spreadsheet (with a column name and row labels).\n",
    "* `DataFrame` objects. This is a 2D table, similar to a spreadsheet (with column names and row labels).\n",
    "* `Panel` objects. You can see a `Panel` as a dictionary of `DataFrame`s. These are less used, so we will not discuss them here."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Creating a `Series`\n",
    "Let's start by creating our first `Series` object!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0    2\n",
       "1   -1\n",
       "2    3\n",
       "3    5\n",
       "dtype: int64"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s = pd.Series([2,-1,3,5])\n",
    "s"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Similar to a 1D `ndarray`\n",
    "`Series` objects behave much like one-dimensional NumPy `ndarray`s, and you can often pass them as parameters to NumPy functions:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0      7.389056\n",
       "1      0.367879\n",
       "2     20.085537\n",
       "3    148.413159\n",
       "dtype: float64"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import numpy as np\n",
    "np.exp(s)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Arithmetic operations on `Series` are also possible, and they apply *elementwise*, just like for `ndarray`s:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0    1002\n",
       "1    1999\n",
       "2    3003\n",
       "3    4005\n",
       "dtype: int64"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s + [1000,2000,3000,4000]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Similar to NumPy, if you add a single number to a `Series`, that number is added to all items in the `Series`. This is called * broadcasting*:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0    1002\n",
       "1     999\n",
       "2    1003\n",
       "3    1005\n",
       "dtype: int64"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s + 1000"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The same is true for all binary operations such as `*` or `/`, and even conditional operations:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0    False\n",
       "1     True\n",
       "2    False\n",
       "3    False\n",
       "dtype: bool"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s < 0"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Index labels\n",
    "Each item in a `Series` object has a unique identifier called the *index label*. By default, it is simply the rank of the item in the `Series` (starting at `0`) but you can also set the index labels manually:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "alice       68\n",
       "bob         83\n",
       "charles    112\n",
       "darwin      68\n",
       "dtype: int64"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s2 = pd.Series([68, 83, 112, 68], index=[\"alice\", \"bob\", \"charles\", \"darwin\"])\n",
    "s2"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can then use the `Series` just like a `dict`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "83"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s2[\"bob\"]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can still access the items by integer location, like in a regular array:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "83"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s2[1]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To make it clear when you are accessing by label or by integer location, it is recommended to always use the `loc` attribute when accessing by label, and the `iloc` attribute when accessing by integer location:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "83"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s2.loc[\"bob\"]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "83"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s2.iloc[1]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Slicing a `Series` also slices the index labels:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "bob         83\n",
       "charles    112\n",
       "dtype: int64"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s2.iloc[1:3]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This can lead to unexpected results when using the default numeric labels, so be careful:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0    1000\n",
       "1    1001\n",
       "2    1002\n",
       "3    1003\n",
       "dtype: int64"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "surprise = pd.Series([1000, 1001, 1002, 1003])\n",
    "surprise"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2    1002\n",
       "3    1003\n",
       "dtype: int64"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "surprise_slice = surprise[2:]\n",
    "surprise_slice"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Oh look! The first element has index label `2`. The element with index label `0` is absent from the slice:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Key error: 0\n"
     ]
    }
   ],
   "source": [
    "try:\n",
    "    surprise_slice[0]\n",
    "except KeyError as e:\n",
    "    print(\"Key error:\", e)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "But remember that you can access elements by integer location using the `iloc` attribute. This illustrates another reason why it's always better to use `loc` and `iloc` to access `Series` objects:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1002"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "surprise_slice.iloc[0]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Init from `dict`\n",
    "You can create a `Series` object from a `dict`. The keys will be used as index labels:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "alice     68\n",
       "bob       83\n",
       "colin     86\n",
       "darwin    68\n",
       "dtype: int64"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "weights = {\"alice\": 68, \"bob\": 83, \"colin\": 86, \"darwin\": 68}\n",
    "s3 = pd.Series(weights)\n",
    "s3"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can control which elements you want to include in the `Series` and in what order by explicitly specifying the desired `index`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "colin    86\n",
       "alice    68\n",
       "dtype: int64"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s4 = pd.Series(weights, index = [\"colin\", \"alice\"])\n",
    "s4"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Automatic alignment\n",
    "When an operation involves multiple `Series` objects, `pandas` automatically aligns items by matching index labels."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Index([u'alice', u'bob', u'charles', u'darwin'], dtype='object')\n",
      "Index([u'alice', u'bob', u'colin', u'darwin'], dtype='object')\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "alice      136\n",
       "bob        166\n",
       "charles    NaN\n",
       "colin      NaN\n",
       "darwin     136\n",
       "dtype: float64"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "print(s2.keys())\n",
    "print(s3.keys())\n",
    "\n",
    "s2 + s3"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The resulting `Series` contains the union of index labels from `s2` and `s3`. Since `\"colin\"` is missing from `s2` and `\"charles\"` is missing from `s3`, these items have a `NaN` result value. (ie. Not-a-Number means *missing*).\n",
    "\n",
    "Automatic alignment is very handy when working with data that may come from various sources with varying structure and missing items. But if you forget to set the right index labels, you can have surprising results:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "s2 = [ 68  83 112  68]\n",
      "s5 = [1000 1000 1000 1000]\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "0         NaN\n",
       "1         NaN\n",
       "2         NaN\n",
       "3         NaN\n",
       "alice     NaN\n",
       "bob       NaN\n",
       "charles   NaN\n",
       "darwin    NaN\n",
       "dtype: float64"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s5 = pd.Series([1000,1000,1000,1000])\n",
    "print(\"s2 =\", s2.values)\n",
    "print(\"s5 =\", s5.values)\n",
    "\n",
    "s2 + s5"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Pandas could not align the `Series`, since their labels do not match at all, hence the full `NaN` result."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Init with a scalar\n",
    "You can also initialize a `Series` object using a scalar and a list of index labels: all items will be set to the scalar."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "life          42\n",
       "universe      42\n",
       "everything    42\n",
       "dtype: int64"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "meaning = pd.Series(42, [\"life\", \"universe\", \"everything\"])\n",
    "meaning"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## `Series` name\n",
    "A `Series` can have a `name`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "bob      83\n",
       "alice    68\n",
       "Name: weights, dtype: int64"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s6 = pd.Series([83, 68], index=[\"bob\", \"alice\"], name=\"weights\")\n",
    "s6"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Plotting a `Series`\n",
    "Pandas makes it easy to plot `Series` data using matplotlib (for more details on matplotlib, check out the [matplotlib tutorial](tools_matplotlib.ipynb)). Just import matplotlib and call the `plot` method:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "collapsed": false,
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x10ce99ed0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "%matplotlib inline\n",
    "import matplotlib.pyplot as plt\n",
    "temperatures = [4.4,5.1,6.1,6.2,6.1,6.1,5.7,5.2,4.7,4.1,3.9,3.5]\n",
    "s7 = pd.Series(temperatures, name=\"Temperature\")\n",
    "s7.plot()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "There are *many* options for plotting your data. It is not necessary to list them all here: if you need a particular type of plot (histograms, pie charts, etc.), just look for it in the excellent [Visualization](http://pandas.pydata.org/pandas-docs/stable/visualization.html) section of pandas' documentation, and look at the example code."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Handling time\n",
    "Many datasets have timestamps, and pandas is awesome at manipulating such data:\n",
    "* it can represent periods (such as 2016Q3) and frequencies (such as \"monthly\"),\n",
    "* it can convert periods to actual timestamps, and *vice versa*,\n",
    "* it can resample data and aggregate values any way you like,\n",
    "* it can handle timezones.\n",
    "\n",
    "## Time range\n",
    "Let's start by creating a time series using `timerange`. This returns a `DatetimeIndex` containing one datetime per hour for 12 hours starting on October 29th 2016 at 5:30pm."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DatetimeIndex(['2016-10-29 17:30:00', '2016-10-29 18:30:00',\n",
       "               '2016-10-29 19:30:00', '2016-10-29 20:30:00',\n",
       "               '2016-10-29 21:30:00', '2016-10-29 22:30:00',\n",
       "               '2016-10-29 23:30:00', '2016-10-30 00:30:00',\n",
       "               '2016-10-30 01:30:00', '2016-10-30 02:30:00',\n",
       "               '2016-10-30 03:30:00', '2016-10-30 04:30:00'],\n",
       "              dtype='datetime64[ns]', freq='H')"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dates = pd.date_range('2016/10/29 5:30pm', periods=12, freq='H')\n",
    "dates"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This `DatetimeIndex` may be used as an index in a `Series`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2016-10-29 17:30:00    4.4\n",
       "2016-10-29 18:30:00    5.1\n",
       "2016-10-29 19:30:00    6.1\n",
       "2016-10-29 20:30:00    6.2\n",
       "2016-10-29 21:30:00    6.1\n",
       "2016-10-29 22:30:00    6.1\n",
       "2016-10-29 23:30:00    5.7\n",
       "2016-10-30 00:30:00    5.2\n",
       "2016-10-30 01:30:00    4.7\n",
       "2016-10-30 02:30:00    4.1\n",
       "2016-10-30 03:30:00    3.9\n",
       "2016-10-30 04:30:00    3.5\n",
       "Freq: H, dtype: float64"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "temp_series = pd.Series(temperatures, dates)\n",
    "temp_series"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's plot this series:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAWcAAAFgCAYAAABnvbg1AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAG51JREFUeJzt3XuQpFd93vHn0a7AuqAdJMGuy0IaDEUwxmQiBURZVBhZ\nXBQSS0UKEAJjj5MCV2yMy1YCBGJLOAWxKYPBFZP4IsDYBiEu5uLYQcLQwgiDQLuNbquF2IwkiFdR\npJUMCGIs/fxHv6Od7Z2Z7p4+ffqc9/1+q6Z2+jLvp3tHOjvzm7fPOCJERERldcy8HwARER0dizMR\nUYGxOBMRFRiLMxFRgbE4ExEVGIszEVGBjVycbT/B9j7be5s/77P9qhwPjoioq3mS85xtHyPp65LO\njog7ZvaoiIg63qRjjWdJ+msWZiKi2Tbp4nyRpPfN4oEQEdHhxh5r2D5W0v+R9KSIuGuD23kdOBHR\nhEWEN7p+kq+c/6Wk6zdamNchE79deuml2/q40i08PLzueNu1tmqSxfliMdIgIsrSWIuz7eM1+GHg\nh1M/gNXV1dSHLMLCw8PrjjcLa+c4d4qI+yU9KrkuaWlpaRaHnbuFh4fXHW8W1kTnOW95IDtSHYuI\nqAvZViT4gSAREWVq7otzr9drpYWHh9cdbxbW3BdnIiI6OmbORERzipkzEVFlzX1xrn0uhIeHh8fM\nmYioIzFzJiKaU8yciYgqa+6Lc+1zITw8PDxmzkREHYmZMxHRnGLmTERUWXNfnGufC+Hh4eExcyYi\n6kjMnImI5hQzZyKiypr74lz7XAgPDw+PmTMRUUdi5kxENKeYObeoPXsWZXvitz17Fuf90Ilogua+\nONc+F8rt3XnnbZJik7dPb3rb4OPS1oa/Tzy8Uq2xFmfbu2x/wPZ+2zfbPjv5IyEioocaa+Zs+92S\nromId9neKen4iPi7oft0cua8Z8/itr4q3b37DB08uDrxx9nW4KvhiT9S2/n85H5+uT2iebbVzHnk\n4mz7JEn7IuJxI+7XycU592KJl9YjmmfT/kDwsZL+n+132d5r+3dtH5fqwdU+Fxoh4lXstXlGile+\ntXPM+5wp6eci4ku23ybptZIuHb7jysqKFhcXJUkLCwtaWlrS8vKypMMPfvjyWpvdnvJyv99Pfvx1\nz6D5c3nd5f7Q5fW3D46BN18v938veO30+v3+WPdfe391dVWjGmessVvSX0XEDzaXnyHpNRHx40P3\nY6wx2UdW8W1/2z2ieTbVWCMi7pR0h+0nNFedJ+mWhI+PiIiGGvc851dJ+mPbfUn/VNKbUj2Ao7+d\nnV05rUbEq9jL/d8LXr3eLKxxZs6KiC9LempynYiINoy9Naas7TPZtntE84y9NYiIKmvui3Ptc6ER\nIl7FXptnpHjlW3NfnImI6OiYOU9Z22eybfeI5hkzZ6JNYn9sKrW5L861z4VGiHiFe+yPjVeqNffF\nmYiIjo6Z85S1fSaLl9YjWh8zZyKiypr74lz7XGiEiIc3vtbimWzbPWbOREQdiZnzlLV9RoqX1iNa\nHzNnIqLKmvviXPtcaISIhze+1uKZbNs9Zs5ERB2JmfOUtX1GipfWI1ofM2ciosqa++Jc+1xohIiH\nN77W4pls2z1mzkREHYmZ85S1fUaKl9YjWh8zZ6JCYv9oGre5L861z4VGiHh4R8T+0e30ZmHtHOdO\ntlcl3SfpQUnfi4inJX8kRET0UGPNnG3/jaSzIuLQFvcpYua8Z8/itr7K2L37DB08uDrxx7V9RopX\nt0dlt9XMeayvnCVZBYxAxunwt42TftyGfz9ERHNp3AU3JF1t+4u2X57yAeSdQ+W08PDK9to8A87t\nzW3mLOmciPhb24/SYJHeHxGfHb7TysqKFhcXJUkLCwtaWlrS8vKypMMPfvjyWpvdPunldUds/lxe\nd7k/dHn97YNj4OG1ydvqcr/fT3q8Lnv9fn+s+6+9v7q6qlFNfJ6z7UslfTMi3jp0fREz57bPEPHw\nqD1NdZ6z7eNtn9i8f4Kk50i6Ke1DJCKi9Y0zc94t6bO290n6vKSPR8RVqR5A3jlUTgsPr2yvzTPg\n3N4srJEz54j4mqSl5DIREW1a6/bWaPsMEQ+P2hN7axARVdbcF2dmznh48/HaPAPO7c3CmvviTERE\nR8fM+fBHVjFDxMOj9sTMmaijsX90vc19cWbmjIc3O4/9o+u15r44ExHR0TFzPvyRVcwQ8fBK9miy\nmDkTEVXW3BdnZs54eN3wmDlP1twXZyIiOjpmzoc/soqZHh5eyR5NFjNnIqLKyrI4l3MifC/x8fDw\n8MbWmDlPVJbFuaQT4YmIaijLzDnn3KvtMz08vJI9mixmzkRElVXA4txrqYWHh3eExsx5ogpYnImI\naDhmzlNYeHh4NE3MnImIKquAxbnXUgsPD+8IjZnzRI29ONs+xvZe2x9L/iiIiOiIxp452/5FSWdJ\n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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x10a109790>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "temp_series.plot(kind=\"bar\")\n",
    "\n",
    "plt.grid(True)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Resampling\n",
    "Pandas let's us resample a time series very simply. Just call the `resample` method and specify a new frequency:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2016-10-29 16:00:00    4.40\n",
       "2016-10-29 18:00:00    5.60\n",
       "2016-10-29 20:00:00    6.15\n",
       "2016-10-29 22:00:00    5.90\n",
       "2016-10-30 00:00:00    4.95\n",
       "2016-10-30 02:00:00    4.00\n",
       "2016-10-30 04:00:00    3.50\n",
       "Freq: 2H, dtype: float64"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "temp_series_freq_2H = temp_series.resample(\"2H\")\n",
    "temp_series_freq_2H"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's take a look at the result:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\nAAAAAElFTkSuQmCC\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x108542350>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "temp_series_freq_2H.plot(kind=\"bar\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Note how the values have automatically been aggregated into 2-hour periods. If we look at the 6-8pm period, for example, we had a value of `5.1` at 6:30pm, and `6.1` at 7:30pm. After resampling, we just have one value of `5.6`, which is the mean of `5.1` and `6.1`. Computing the mean is the default behavior, but it is also possible to use a different aggregation function, for example we can decide to keep the minimum value of each period:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2016-10-29 16:00:00    4.4\n",
       "2016-10-29 18:00:00    5.1\n",
       "2016-10-29 20:00:00    6.1\n",
       "2016-10-29 22:00:00    5.7\n",
       "2016-10-30 00:00:00    4.7\n",
       "2016-10-30 02:00:00    3.9\n",
       "2016-10-30 04:00:00    3.5\n",
       "Freq: 2H, dtype: float64"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "temp_series_freq_2H = temp_series.resample(\"2H\", how=np.min)\n",
    "temp_series_freq_2H"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Upsampling and interpolation\n",
    "This was an example of downsampling. We can also upsample (ie. increase the frequency), but this creates holes in our data:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2016-10-29 17:30:00    4.4\n",
       "2016-10-29 17:45:00    NaN\n",
       "2016-10-29 18:00:00    NaN\n",
       "2016-10-29 18:15:00    NaN\n",
       "2016-10-29 18:30:00    5.1\n",
       "2016-10-29 18:45:00    NaN\n",
       "2016-10-29 19:00:00    NaN\n",
       "2016-10-29 19:15:00    NaN\n",
       "2016-10-29 19:30:00    6.1\n",
       "2016-10-29 19:45:00    NaN\n",
       "Freq: 15T, dtype: float64"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "temp_series_freq_15min = temp_series.resample(\"15Min\")\n",
    "temp_series_freq_15min.head(n=10) # `head` displays the top n values"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "One solution is to fill the gaps by interpolating. We just call the `interpolate` method. The default is to use linear interpolation, but we can also select another method, such as cubic interpolation:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {
    "collapsed": false,
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2016-10-29 17:30:00    4.400000\n",
       "2016-10-29 17:45:00    4.430644\n",
       "2016-10-29 18:00:00    4.582074\n",
       "2016-10-29 18:15:00    4.817467\n",
       "2016-10-29 18:30:00    5.100000\n",
       "2016-10-29 18:45:00    5.394958\n",
       "2016-10-29 19:00:00    5.676060\n",
       "2016-10-29 19:15:00    5.919132\n",
       "2016-10-29 19:30:00    6.100000\n",
       "2016-10-29 19:45:00    6.202023\n",
       "Freq: 15T, dtype: float64"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "temp_series_freq_15min = temp_series.resample(\"15Min\").interpolate(method=\"cubic\")\n",
    "temp_series_freq_15min.head(n=10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x10aef3ed0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "temp_series.plot(label=\"Period: 1 hour\")\n",
    "temp_series_freq_15min.plot(label=\"Period: 15 minutes\")\n",
    "plt.legend()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Timezones\n",
    "By default datetimes are *naive*: they are not aware of timezones, so 2016-10-30 02:30 might mean October 30th 2016 at 2:30am in Paris or in New York. We can make datetimes timezone *aware* by calling the `tz_localize` method:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2016-10-29 17:30:00-04:00    4.4\n",
       "2016-10-29 18:30:00-04:00    5.1\n",
       "2016-10-29 19:30:00-04:00    6.1\n",
       "2016-10-29 20:30:00-04:00    6.2\n",
       "2016-10-29 21:30:00-04:00    6.1\n",
       "2016-10-29 22:30:00-04:00    6.1\n",
       "2016-10-29 23:30:00-04:00    5.7\n",
       "2016-10-30 00:30:00-04:00    5.2\n",
       "2016-10-30 01:30:00-04:00    4.7\n",
       "2016-10-30 02:30:00-04:00    4.1\n",
       "2016-10-30 03:30:00-04:00    3.9\n",
       "2016-10-30 04:30:00-04:00    3.5\n",
       "Freq: H, dtype: float64"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "temp_series_ny = temp_series.tz_localize(\"America/New_York\")\n",
    "temp_series_ny"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Note that `-04:00` is now appended to all the datetimes. This means that these datetimes refer to [UTC](https://en.wikipedia.org/wiki/Coordinated_Universal_Time) - 4 hours.\n",
    "\n",
    "We can convert these datetimes to Paris time like this:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2016-10-29 23:30:00+02:00    4.4\n",
       "2016-10-30 00:30:00+02:00    5.1\n",
       "2016-10-30 01:30:00+02:00    6.1\n",
       "2016-10-30 02:30:00+02:00    6.2\n",
       "2016-10-30 02:30:00+01:00    6.1\n",
       "2016-10-30 03:30:00+01:00    6.1\n",
       "2016-10-30 04:30:00+01:00    5.7\n",
       "2016-10-30 05:30:00+01:00    5.2\n",
       "2016-10-30 06:30:00+01:00    4.7\n",
       "2016-10-30 07:30:00+01:00    4.1\n",
       "2016-10-30 08:30:00+01:00    3.9\n",
       "2016-10-30 09:30:00+01:00    3.5\n",
       "Freq: H, dtype: float64"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "temp_series_paris = temp_series_ny.tz_convert(\"Europe/Paris\")\n",
    "temp_series_paris"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You may have noticed that the UTC offset changes from `+02:00` to `+01:00`: this is because France switches to winter time at 3am that particular night (time goes back to 2am). Notice that 2:30am occurs twice! Let's go back to a naive representation (if you log some data hourly using local time, without storing the timezone, you might get something like this):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2016-10-29 23:30:00    4.4\n",
       "2016-10-30 00:30:00    5.1\n",
       "2016-10-30 01:30:00    6.1\n",
       "2016-10-30 02:30:00    6.2\n",
       "2016-10-30 02:30:00    6.1\n",
       "2016-10-30 03:30:00    6.1\n",
       "2016-10-30 04:30:00    5.7\n",
       "2016-10-30 05:30:00    5.2\n",
       "2016-10-30 06:30:00    4.7\n",
       "2016-10-30 07:30:00    4.1\n",
       "2016-10-30 08:30:00    3.9\n",
       "2016-10-30 09:30:00    3.5\n",
       "Freq: H, dtype: float64"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "temp_series_paris_naive = temp_series_paris.tz_localize(None)\n",
    "temp_series_paris_naive"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now `02:30` is really ambiguous. If we try to localize these naive datetimes to the Paris timezone, we get an error:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pytz.exceptions.AmbiguousTimeError'>\n",
      "Cannot infer dst time from Timestamp('2016-10-30 02:30:00'), try using the 'ambiguous' argument\n"
     ]
    }
   ],
   "source": [
    "try:\n",
    "    temp_series_paris_naive.tz_localize(\"Europe/Paris\")\n",
    "except Exception as e:\n",
    "    print(type(e))\n",
    "    print(e)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Fortunately using the `ambiguous` argument we can tell pandas to infer the right DST (Daylight Saving Time) based on the order of the ambiguous timestamps:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2016-10-29 23:30:00+02:00    4.4\n",
       "2016-10-30 00:30:00+02:00    5.1\n",
       "2016-10-30 01:30:00+02:00    6.1\n",
       "2016-10-30 02:30:00+02:00    6.2\n",
       "2016-10-30 02:30:00+01:00    6.1\n",
       "2016-10-30 03:30:00+01:00    6.1\n",
       "2016-10-30 04:30:00+01:00    5.7\n",
       "2016-10-30 05:30:00+01:00    5.2\n",
       "2016-10-30 06:30:00+01:00    4.7\n",
       "2016-10-30 07:30:00+01:00    4.1\n",
       "2016-10-30 08:30:00+01:00    3.9\n",
       "2016-10-30 09:30:00+01:00    3.5\n",
       "Freq: H, dtype: float64"
      ]
     },
     "execution_count": 38,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "temp_series_paris_naive.tz_localize(\"Europe/Paris\", ambiguous=\"infer\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Periods\n",
    "The `period_range` function returns a `PeriodIndex` instead of a `DatetimeIndex`. For example, let's get all quarters in 2016 and 2017:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "PeriodIndex(['2016Q1', '2016Q2', '2016Q3', '2016Q4', '2017Q1', '2017Q2',\n",
       "             '2017Q3', '2017Q4'],\n",
       "            dtype='int64', freq='Q-DEC')"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "quarters = pd.period_range('2016Q1', periods=8, freq='Q')\n",
    "quarters"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Adding a number `N` to a `PeriodIndex` shifts the periods by `N` times the `PeriodIndex`'s frequency:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "PeriodIndex(['2016Q4', '2017Q1', '2017Q2', '2017Q3', '2017Q4', '2018Q1',\n",
       "             '2018Q2', '2018Q3'],\n",
       "            dtype='int64', freq='Q-DEC')"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "quarters + 3"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The `asfreq` method lets us change the frequency of the `PeriodIndex`. All periods are lengthened or shortened accordingly. For example, let's convert all the quarterly periods to monthly periods (zooming in):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "PeriodIndex(['2016-03', '2016-06', '2016-09', '2016-12', '2017-03', '2017-06',\n",
       "             '2017-09', '2017-12'],\n",
       "            dtype='int64', freq='M')"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "quarters.asfreq(\"M\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "By default, the `asfreq` zooms on the end of each period. We can tell it to zoom on the start of each period instead:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "PeriodIndex(['2016-01', '2016-04', '2016-07', '2016-10', '2017-01', '2017-04',\n",
       "             '2017-07', '2017-10'],\n",
       "            dtype='int64', freq='M')"
      ]
     },
     "execution_count": 42,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "quarters.asfreq(\"M\", how=\"start\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "And we can zoom out:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "PeriodIndex(['2016', '2016', '2016', '2016', '2017', '2017', '2017', '2017'], dtype='int64', freq='A-DEC')"
      ]
     },
     "execution_count": 43,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "quarters.asfreq(\"A\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Of course we can create a `Series` with a `PeriodIndex`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2016Q1    300\n",
       "2016Q2    320\n",
       "2016Q3    290\n",
       "2016Q4    390\n",
       "2017Q1    320\n",
       "2017Q2    360\n",
       "2017Q3    310\n",
       "2017Q4    410\n",
       "Freq: Q-DEC, dtype: int64"
      ]
     },
     "execution_count": 44,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "quarterly_revenue = pd.Series([300, 320, 290, 390, 320, 360, 310, 410], index = quarters)\n",
    "quarterly_revenue"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n1GywAAAAAElFTkSuQmCC\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x10c056650>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "quarterly_revenue.plot(kind=\"line\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can convert periods to timestamps by calling `to_timestamp`. By default this will give us the first day of each period, but by setting `how` and `freq`, we can get the last hour of each period:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2016-03-31 23:00:00    300\n",
       "2016-06-30 23:00:00    320\n",
       "2016-09-30 23:00:00    290\n",
       "2016-12-31 23:00:00    390\n",
       "2017-03-31 23:00:00    320\n",
       "2017-06-30 23:00:00    360\n",
       "2017-09-30 23:00:00    310\n",
       "2017-12-31 23:00:00    410\n",
       "Freq: Q-DEC, dtype: int64"
      ]
     },
     "execution_count": 46,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "last_hours = quarterly_revenue.to_timestamp(how=\"end\", freq=\"H\")\n",
    "last_hours"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "And back to periods by calling `to_period`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2016Q1    300\n",
       "2016Q2    320\n",
       "2016Q3    290\n",
       "2016Q4    390\n",
       "2017Q1    320\n",
       "2017Q2    360\n",
       "2017Q3    310\n",
       "2017Q4    410\n",
       "Freq: Q-DEC, dtype: int64"
      ]
     },
     "execution_count": 47,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "last_hours.to_period()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Pandas also provides many other time-related functions that we recommend you check out in the [documentation](http://pandas.pydata.org/pandas-docs/stable/timeseries.html). To whet your appetite, here is one way to get the last business day of each month in 2016, at 9am:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "PeriodIndex(['2016-01-29 09:00', '2016-02-29 09:00', '2016-03-31 09:00',\n",
       "             '2016-04-29 09:00', '2016-05-31 09:00', '2016-06-30 09:00',\n",
       "             '2016-07-29 09:00', '2016-08-31 09:00', '2016-09-30 09:00',\n",
       "             '2016-10-31 09:00', '2016-11-30 09:00', '2016-12-30 09:00'],\n",
       "            dtype='int64', freq='H')"
      ]
     },
     "execution_count": 48,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "months_2016 = pd.period_range(\"2016\", periods=12, freq=\"M\")\n",
    "one_day_after_last_days = months_2016.asfreq(\"D\") + 1\n",
    "last_bdays = one_day_after_last_days.to_timestamp() - pd.tseries.offsets.BDay()\n",
    "last_bdays.to_period(\"H\") + 9"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# `DataFrame` objects\n",
    "A DataFrame object represents a spreadsheet, with cell values, column names and row index labels. You can define expressions to compute columns based on other columns, create pivot-tables, group rows, draw graphs, etc. You can see `DataFrame`s as dictionaries of `Series`.\n",
    "\n",
    "## Creating a `DataFrame`\n",
    "You can create a DataFrame by passing a dictionary of `Series` objects:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>birthyear</th>\n",
       "      <th>children</th>\n",
       "      <th>hobby</th>\n",
       "      <th>weight</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>alice</th>\n",
       "      <td>1985</td>\n",
       "      <td>NaN</td>\n",
       "      <td>Biking</td>\n",
       "      <td>68</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>bob</th>\n",
       "      <td>1984</td>\n",
       "      <td>3</td>\n",
       "      <td>Dancing</td>\n",
       "      <td>83</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>charles</th>\n",
       "      <td>1992</td>\n",
       "      <td>0</td>\n",
       "      <td>NaN</td>\n",
       "      <td>112</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "         birthyear  children    hobby  weight\n",
       "alice         1985       NaN   Biking      68\n",
       "bob           1984         3  Dancing      83\n",
       "charles       1992         0      NaN     112"
      ]
     },
     "execution_count": 49,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "people_dict = {\n",
    "    \"weight\": pd.Series([68, 83, 112], index=[\"alice\", \"bob\", \"charles\"]),\n",
    "    \"birthyear\": pd.Series([1984, 1985, 1992], index=[\"bob\", \"alice\", \"charles\"], name=\"year\"),\n",
    "    \"children\": pd.Series([0, 3], index=[\"charles\", \"bob\"]),\n",
    "    \"hobby\": pd.Series([\"Biking\", \"Dancing\"], index=[\"alice\", \"bob\"]),\n",
    "}\n",
    "people = pd.DataFrame(people_dict)\n",
    "people"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "A few things to note:\n",
    "* the `Series` were automatically aligned based on their index,\n",
    "* missing values are represented as `NaN`,\n",
    "* `Series` names are ignored (the name `\"year\"` was dropped),\n",
    "* `DataFrame`s are displayed nicely in Jupyter notebooks, woohoo!"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can access columns pretty much as you would expect. They are returned as `Series` objects:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "alice      1985\n",
       "bob        1984\n",
       "charles    1992\n",
       "Name: birthyear, dtype: int64"
      ]
     },
     "execution_count": 50,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "people[\"birthyear\"]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can also get multiple columns at once:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>birthyear</th>\n",
       "      <th>hobby</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>alice</th>\n",
       "      <td>1985</td>\n",
       "      <td>Biking</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>bob</th>\n",
       "      <td>1984</td>\n",
       "      <td>Dancing</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>charles</th>\n",
       "      <td>1992</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "         birthyear    hobby\n",
       "alice         1985   Biking\n",
       "bob           1984  Dancing\n",
       "charles       1992      NaN"
      ]
     },
     "execution_count": 51,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "people[[\"birthyear\", \"hobby\"]]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If you pass a list of columns and/or index row labels to the `DataFrame` constructor, it will guarantee that these columns and/or rows will exist, in that order, and no other column/row will exist. For example:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>birthyear</th>\n",
       "      <th>weight</th>\n",
       "      <th>height</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>bob</th>\n",
       "      <td>1984</td>\n",
       "      <td>83</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>alice</th>\n",
       "      <td>1985</td>\n",
       "      <td>68</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>eugene</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "        birthyear  weight height\n",
       "bob          1984      83    NaN\n",
       "alice        1985      68    NaN\n",
       "eugene        NaN     NaN    NaN"
      ]
     },
     "execution_count": 52,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "d2 = pd.DataFrame(\n",
    "        people_dict,\n",
    "        columns=[\"birthyear\", \"weight\", \"height\"],\n",
    "        index=[\"bob\", \"alice\", \"eugene\"]\n",
    "     )\n",
    "d2"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Another convenient way to create a `DataFrame` is to pass all the values to the constructor as an `ndarray`, or a list of lists, and specify the column names and row index labels separately:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>birthyear</th>\n",
       "      <th>children</th>\n",
       "      <th>hobby</th>\n",
       "      <th>weight</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>alice</th>\n",
       "      <td>1985</td>\n",
       "      <td>NaN</td>\n",
       "      <td>Biking</td>\n",
       "      <td>68</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>bob</th>\n",
       "      <td>1984</td>\n",
       "      <td>3</td>\n",
       "      <td>Dancing</td>\n",
       "      <td>83</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>charles</th>\n",
       "      <td>1992</td>\n",
       "      <td>0</td>\n",
       "      <td>NaN</td>\n",
       "      <td>112</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "         birthyear  children    hobby  weight\n",
       "alice         1985       NaN   Biking      68\n",
       "bob           1984         3  Dancing      83\n",
       "charles       1992         0      NaN     112"
      ]
     },
     "execution_count": 53,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "values = [\n",
    "            [1985, np.nan, \"Biking\",   68],\n",
    "            [1984, 3,      \"Dancing\",  83],\n",
    "            [1992, 0,      np.nan,    112]\n",
    "         ]\n",
    "d3 = pd.DataFrame(\n",
    "        values,\n",
    "        columns=[\"birthyear\", \"children\", \"hobby\", \"weight\"],\n",
    "        index=[\"alice\", \"bob\", \"charles\"]\n",
    "     )\n",
    "d3"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To specify missing values, you can either use `np.nan` or NumPy's masked arrays:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>birthyear</th>\n",
       "      <th>children</th>\n",
       "      <th>hobby</th>\n",
       "      <th>weight</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>alice</th>\n",
       "      <td>1985</td>\n",
       "      <td>NaN</td>\n",
       "      <td>Biking</td>\n",
       "      <td>68</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>bob</th>\n",
       "      <td>1984</td>\n",
       "      <td>3</td>\n",
       "      <td>Dancing</td>\n",
       "      <td>83</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>charles</th>\n",
       "      <td>1992</td>\n",
       "      <td>0</td>\n",
       "      <td>NaN</td>\n",
       "      <td>112</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "         birthyear  children    hobby  weight\n",
       "alice         1985       NaN   Biking      68\n",
       "bob           1984         3  Dancing      83\n",
       "charles       1992         0      NaN     112"
      ]
     },
     "execution_count": 54,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "masked_array = np.ma.asarray(values, dtype=np.object)\n",
    "masked_array[(0, 2), (1, 2)] = np.ma.masked\n",
    "d3 = pd.DataFrame(\n",
    "        values,\n",
    "        columns=[\"birthyear\", \"children\", \"hobby\", \"weight\"],\n",
    "        index=[\"alice\", \"bob\", \"charles\"]\n",
    "     )\n",
    "d3"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Instead of an `ndarray`, you can also pass a `DataFrame` object:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>hobby</th>\n",
       "      <th>children</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>alice</th>\n",
       "      <td>Biking</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>bob</th>\n",
       "      <td>Dancing</td>\n",
       "      <td>3</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "         hobby  children\n",
       "alice   Biking       NaN\n",
       "bob    Dancing         3"
      ]
     },
     "execution_count": 55,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "d4 = pd.DataFrame(\n",
    "         d3,\n",
    "         columns=[\"hobby\", \"children\"],\n",
    "         index=[\"alice\", \"bob\"]\n",
    "     )\n",
    "d4"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "It is also possible to create a `DataFrame` with a dictionary (or list) of dictionaries (or list):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>birthyear</th>\n",
       "      <th>children</th>\n",
       "      <th>hobby</th>\n",
       "      <th>weight</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>alice</th>\n",
       "      <td>1985</td>\n",
       "      <td>NaN</td>\n",
       "      <td>Biking</td>\n",
       "      <td>68</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>bob</th>\n",
       "      <td>1984</td>\n",
       "      <td>3</td>\n",
       "      <td>Dancing</td>\n",
       "      <td>83</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>charles</th>\n",
       "      <td>1992</td>\n",
       "      <td>0</td>\n",
       "      <td>NaN</td>\n",
       "      <td>112</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "         birthyear  children    hobby  weight\n",
       "alice         1985       NaN   Biking      68\n",
       "bob           1984         3  Dancing      83\n",
       "charles       1992         0      NaN     112"
      ]
     },
     "execution_count": 56,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "people = pd.DataFrame({\n",
    "    \"birthyear\": {\"alice\":1985, \"bob\": 1984, \"charles\": 1992},\n",
    "    \"hobby\": {\"alice\":\"Biking\", \"bob\": \"Dancing\"},\n",
    "    \"weight\": {\"alice\":68, \"bob\": 83, \"charles\": 112},\n",
    "    \"children\": {\"bob\": 3, \"charles\": 0}\n",
    "})\n",
    "people"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Multi-indexing\n",
    "If all columns are tuples of the same size, then they are understood as a multi-index. The same goes for row index labels. For example:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th colspan=\"2\" halign=\"left\">private</th>\n",
       "      <th colspan=\"2\" halign=\"left\">public</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>children</th>\n",
       "      <th>weight</th>\n",
       "      <th>birthyear</th>\n",
       "      <th>hobby</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>London</th>\n",
       "      <th>charles</th>\n",
       "      <td>0</td>\n",
       "      <td>112</td>\n",
       "      <td>1992</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">Paris</th>\n",
       "      <th>alice</th>\n",
       "      <td>NaN</td>\n",
       "      <td>68</td>\n",
       "      <td>1985</td>\n",
       "      <td>Biking</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>bob</th>\n",
       "      <td>3</td>\n",
       "      <td>83</td>\n",
       "      <td>1984</td>\n",
       "      <td>Dancing</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                private           public         \n",
       "               children weight birthyear    hobby\n",
       "London charles        0    112      1992      NaN\n",
       "Paris  alice        NaN     68      1985   Biking\n",
       "       bob            3     83      1984  Dancing"
      ]
     },
     "execution_count": 57,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "d5 = pd.DataFrame(\n",
    "  {\n",
    "    (\"public\", \"birthyear\"):\n",
    "        {(\"Paris\",\"alice\"):1985, (\"Paris\",\"bob\"): 1984, (\"London\",\"charles\"): 1992},\n",
    "    (\"public\", \"hobby\"):\n",
    "        {(\"Paris\",\"alice\"):\"Biking\", (\"Paris\",\"bob\"): \"Dancing\"},\n",
    "    (\"private\", \"weight\"):\n",
    "        {(\"Paris\",\"alice\"):68, (\"Paris\",\"bob\"): 83, (\"London\",\"charles\"): 112},\n",
    "    (\"private\", \"children\"):\n",
    "        {(\"Paris\", \"alice\"):np.nan, (\"Paris\",\"bob\"): 3, (\"London\",\"charles\"): 0}\n",
    "  }\n",
    ")\n",
    "d5"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can now get a `DataFrame` containing all the `\"public\"` columns very simply:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>birthyear</th>\n",
       "      <th>hobby</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>London</th>\n",
       "      <th>charles</th>\n",
       "      <td>1992</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">Paris</th>\n",
       "      <th>alice</th>\n",
       "      <td>1985</td>\n",
       "      <td>Biking</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>bob</th>\n",
       "      <td>1984</td>\n",
       "      <td>Dancing</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                birthyear    hobby\n",
       "London charles       1992      NaN\n",
       "Paris  alice         1985   Biking\n",
       "       bob           1984  Dancing"
      ]
     },
     "execution_count": 58,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "d5[\"public\"]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "London  charles        NaN\n",
       "Paris   alice       Biking\n",
       "        bob        Dancing\n",
       "Name: (public, hobby), dtype: object"
      ]
     },
     "execution_count": 59,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "d5[\"public\", \"hobby\"]  # Same result as d4[\"public\"][\"hobby\"]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Dropping a level\n",
    "Let's look at `d5` again:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th colspan=\"2\" halign=\"left\">private</th>\n",
       "      <th colspan=\"2\" halign=\"left\">public</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>children</th>\n",
       "      <th>weight</th>\n",
       "      <th>birthyear</th>\n",
       "      <th>hobby</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>London</th>\n",
       "      <th>charles</th>\n",
       "      <td>0</td>\n",
       "      <td>112</td>\n",
       "      <td>1992</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">Paris</th>\n",
       "      <th>alice</th>\n",
       "      <td>NaN</td>\n",
       "      <td>68</td>\n",
       "      <td>1985</td>\n",
       "      <td>Biking</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>bob</th>\n",
       "      <td>3</td>\n",
       "      <td>83</td>\n",
       "      <td>1984</td>\n",
       "      <td>Dancing</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                private           public         \n",
       "               children weight birthyear    hobby\n",
       "London charles        0    112      1992      NaN\n",
       "Paris  alice        NaN     68      1985   Biking\n",
       "       bob            3     83      1984  Dancing"
      ]
     },
     "execution_count": 60,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "d5"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "There are two levels of columns, and two levels of indices. We can drop a column level by calling `droplevel` (the same goes for indices):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>children</th>\n",
       "      <th>weight</th>\n",
       "      <th>birthyear</th>\n",
       "      <th>hobby</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>London</th>\n",
       "      <th>charles</th>\n",
       "      <td>0</td>\n",
       "      <td>112</td>\n",
       "      <td>1992</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">Paris</th>\n",
       "      <th>alice</th>\n",
       "      <td>NaN</td>\n",
       "      <td>68</td>\n",
       "      <td>1985</td>\n",
       "      <td>Biking</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>bob</th>\n",
       "      <td>3</td>\n",
       "      <td>83</td>\n",
       "      <td>1984</td>\n",
       "      <td>Dancing</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                children  weight  birthyear    hobby\n",
       "London charles         0     112       1992      NaN\n",
       "Paris  alice         NaN      68       1985   Biking\n",
       "       bob             3      83       1984  Dancing"
      ]
     },
     "execution_count": 61,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "d5.columns = d5.columns.droplevel(level = 0)\n",
    "d5"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Transposing\n",
    "You can swap columns and indices using the `T` attribute:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <th>London</th>\n",
       "      <th colspan=\"2\" halign=\"left\">Paris</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <th>charles</th>\n",
       "      <th>alice</th>\n",
       "      <th>bob</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>children</th>\n",
       "      <td>0</td>\n",
       "      <td>NaN</td>\n",
       "      <td>3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>weight</th>\n",
       "      <td>112</td>\n",
       "      <td>68</td>\n",
       "      <td>83</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>birthyear</th>\n",
       "      <td>1992</td>\n",
       "      <td>1985</td>\n",
       "      <td>1984</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>hobby</th>\n",
       "      <td>NaN</td>\n",
       "      <td>Biking</td>\n",
       "      <td>Dancing</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "           London   Paris         \n",
       "          charles   alice      bob\n",
       "children        0     NaN        3\n",
       "weight        112      68       83\n",
       "birthyear    1992    1985     1984\n",
       "hobby         NaN  Biking  Dancing"
      ]
     },
     "execution_count": 62,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "d6 = d5.T\n",
    "d6"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Stacking and unstacking levels\n",
    "Calling the `stack` method will push the lowest column level after the lowest index:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>London</th>\n",
       "      <th>Paris</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">children</th>\n",
       "      <th>bob</th>\n",
       "      <td>NaN</td>\n",
       "      <td>3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>charles</th>\n",
       "      <td>0</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"3\" valign=\"top\">weight</th>\n",
       "      <th>alice</th>\n",
       "      <td>NaN</td>\n",
       "      <td>68</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>bob</th>\n",
       "      <td>NaN</td>\n",
       "      <td>83</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>charles</th>\n",
       "      <td>112</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"3\" valign=\"top\">birthyear</th>\n",
       "      <th>alice</th>\n",
       "      <td>NaN</td>\n",
       "      <td>1985</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>bob</th>\n",
       "      <td>NaN</td>\n",
       "      <td>1984</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>charles</th>\n",
       "      <td>1992</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">hobby</th>\n",
       "      <th>alice</th>\n",
       "      <td>NaN</td>\n",
       "      <td>Biking</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>bob</th>\n",
       "      <td>NaN</td>\n",
       "      <td>Dancing</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                  London    Paris\n",
       "children  bob        NaN        3\n",
       "          charles      0      NaN\n",
       "weight    alice      NaN       68\n",
       "          bob        NaN       83\n",
       "          charles    112      NaN\n",
       "birthyear alice      NaN     1985\n",
       "          bob        NaN     1984\n",
       "          charles   1992      NaN\n",
       "hobby     alice      NaN   Biking\n",
       "          bob        NaN  Dancing"
      ]
     },
     "execution_count": 63,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "d7 = d6.stack()\n",
    "d7"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Note that many `NaN` values appeared. This makes sense because many new combinations did not exist before (eg. there was no `bob` in `London`).\n",
    "\n",
    "Calling `unstack` will do the reverse, once again creating many `NaN` values."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <th colspan=\"3\" halign=\"left\">London</th>\n",
       "      <th colspan=\"3\" halign=\"left\">Paris</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <th>alice</th>\n",
       "      <th>bob</th>\n",
       "      <th>charles</th>\n",
       "      <th>alice</th>\n",
       "      <th>bob</th>\n",
       "      <th>charles</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>children</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>0</td>\n",
       "      <td>NaN</td>\n",
       "      <td>3</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>weight</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>112</td>\n",
       "      <td>68</td>\n",
       "      <td>83</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>birthyear</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>1992</td>\n",
       "      <td>1985</td>\n",
       "      <td>1984</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>hobby</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>Biking</td>\n",
       "      <td>Dancing</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "          London                Paris                 \n",
       "           alice  bob charles   alice      bob charles\n",
       "children     NaN  NaN       0     NaN        3     NaN\n",
       "weight       NaN  NaN     112      68       83     NaN\n",
       "birthyear    NaN  NaN    1992    1985     1984     NaN\n",
       "hobby        NaN  NaN     NaN  Biking  Dancing     NaN"
      ]
     },
     "execution_count": 64,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "d8 = d7.unstack()\n",
    "d8"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If we call `unstack` again, we end up with a `Series` object:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "London  alice    children         NaN\n",
       "                 weight           NaN\n",
       "                 birthyear        NaN\n",
       "                 hobby            NaN\n",
       "        bob      children         NaN\n",
       "                 weight           NaN\n",
       "                 birthyear        NaN\n",
       "                 hobby            NaN\n",
       "        charles  children           0\n",
       "                 weight           112\n",
       "                 birthyear       1992\n",
       "                 hobby            NaN\n",
       "Paris   alice    children         NaN\n",
       "                 weight            68\n",
       "                 birthyear       1985\n",
       "                 hobby         Biking\n",
       "        bob      children           3\n",
       "                 weight            83\n",
       "                 birthyear       1984\n",
       "                 hobby        Dancing\n",
       "        charles  children         NaN\n",
       "                 weight           NaN\n",
       "                 birthyear        NaN\n",
       "                 hobby            NaN\n",
       "dtype: object"
      ]
     },
     "execution_count": 65,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "d9 = d8.unstack()\n",
    "d9"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The `stack` and `unstack` methods let you select the `level` to stack/unstack. You can even stack/unstack multiple levels at once:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "metadata": {
    "collapsed": false,
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <th colspan=\"3\" halign=\"left\">London</th>\n",
       "      <th colspan=\"3\" halign=\"left\">Paris</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <th>alice</th>\n",
       "      <th>bob</th>\n",
       "      <th>charles</th>\n",
       "      <th>alice</th>\n",
       "      <th>bob</th>\n",
       "      <th>charles</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>children</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>0</td>\n",
       "      <td>NaN</td>\n",
       "      <td>3</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>weight</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>112</td>\n",
       "      <td>68</td>\n",
       "      <td>83</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>birthyear</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>1992</td>\n",
       "      <td>1985</td>\n",
       "      <td>1984</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>hobby</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>Biking</td>\n",
       "      <td>Dancing</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "          London                Paris                 \n",
       "           alice  bob charles   alice      bob charles\n",
       "children     NaN  NaN       0     NaN        3     NaN\n",
       "weight       NaN  NaN     112      68       83     NaN\n",
       "birthyear    NaN  NaN    1992    1985     1984     NaN\n",
       "hobby        NaN  NaN     NaN  Biking  Dancing     NaN"
      ]
     },
     "execution_count": 66,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "d10 = d9.unstack(level = (0,1))\n",
    "d10"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Most methods return modified copies\n",
    "As you may have noticed, the `stack` and `unstack` methods do not modify the object they apply to. Instead, they work on a copy and return that copy. This is true of most methods in pandas."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Accessing rows\n",
    "Let's go back to the `people` `DataFrame`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>birthyear</th>\n",
       "      <th>children</th>\n",
       "      <th>hobby</th>\n",
       "      <th>weight</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>alice</th>\n",
       "      <td>1985</td>\n",
       "      <td>NaN</td>\n",
       "      <td>Biking</td>\n",
       "      <td>68</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>bob</th>\n",
       "      <td>1984</td>\n",
       "      <td>3</td>\n",
       "      <td>Dancing</td>\n",
       "      <td>83</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>charles</th>\n",
       "      <td>1992</td>\n",
       "      <td>0</td>\n",
       "      <td>NaN</td>\n",
       "      <td>112</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "         birthyear  children    hobby  weight\n",
       "alice         1985       NaN   Biking      68\n",
       "bob           1984         3  Dancing      83\n",
       "charles       1992         0      NaN     112"
      ]
     },
     "execution_count": 67,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "people"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The `loc` attribute lets you access rows instead of columns. The result is `Series` object in which the `DataFrame`'s column names are mapped to row index labels:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "birthyear    1992\n",
       "children        0\n",
       "hobby         NaN\n",
       "weight        112\n",
       "Name: charles, dtype: object"
      ]
     },
     "execution_count": 68,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "people.loc[\"charles\"]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can also access rows by integer location using the `iloc` attribute:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "birthyear    1992\n",
       "children        0\n",
       "hobby         NaN\n",
       "weight        112\n",
       "Name: charles, dtype: object"
      ]
     },
     "execution_count": 69,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "people.iloc[2]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can also get a slice of rows, and this returns a `DataFrame` object:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 70,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>birthyear</th>\n",
       "      <th>children</th>\n",
       "      <th>hobby</th>\n",
       "      <th>weight</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>bob</th>\n",
       "      <td>1984</td>\n",
       "      <td>3</td>\n",
       "      <td>Dancing</td>\n",
       "      <td>83</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>charles</th>\n",
       "      <td>1992</td>\n",
       "      <td>0</td>\n",
       "      <td>NaN</td>\n",
       "      <td>112</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "         birthyear  children    hobby  weight\n",
       "bob           1984         3  Dancing      83\n",
       "charles       1992         0      NaN     112"
      ]
     },
     "execution_count": 70,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "people.iloc[1:3]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Finally, you can pass a boolean array to get the matching rows:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>birthyear</th>\n",
       "      <th>children</th>\n",
       "      <th>hobby</th>\n",
       "      <th>weight</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>alice</th>\n",
       "      <td>1985</td>\n",
       "      <td>NaN</td>\n",
       "      <td>Biking</td>\n",
       "      <td>68</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>charles</th>\n",
       "      <td>1992</td>\n",
       "      <td>0</td>\n",
       "      <td>NaN</td>\n",
       "      <td>112</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "         birthyear  children   hobby  weight\n",
       "alice         1985       NaN  Biking      68\n",
       "charles       1992         0     NaN     112"
      ]
     },
     "execution_count": 71,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "people[np.array([True, False, True])]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This is most useful when combined with boolean expressions:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 72,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>birthyear</th>\n",
       "      <th>children</th>\n",
       "      <th>hobby</th>\n",
       "      <th>weight</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>alice</th>\n",
       "      <td>1985</td>\n",
       "      <td>NaN</td>\n",
       "      <td>Biking</td>\n",
       "      <td>68</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>bob</th>\n",
       "      <td>1984</td>\n",
       "      <td>3</td>\n",
       "      <td>Dancing</td>\n",
       "      <td>83</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "       birthyear  children    hobby  weight\n",
       "alice       1985       NaN   Biking      68\n",
       "bob         1984         3  Dancing      83"
      ]
     },
     "execution_count": 72,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "people[people[\"birthyear\"] < 1990]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Adding and removing columns\n",
    "You can generally treat `DataFrame` objects like dictionaries of `Series`, so the following work fine:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 73,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>birthyear</th>\n",
       "      <th>children</th>\n",
       "      <th>hobby</th>\n",
       "      <th>weight</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>alice</th>\n",
       "      <td>1985</td>\n",
       "      <td>NaN</td>\n",
       "      <td>Biking</td>\n",
       "      <td>68</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>bob</th>\n",
       "      <td>1984</td>\n",
       "      <td>3</td>\n",
       "      <td>Dancing</td>\n",
       "      <td>83</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>charles</th>\n",
       "      <td>1992</td>\n",
       "      <td>0</td>\n",
       "      <td>NaN</td>\n",
       "      <td>112</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "         birthyear  children    hobby  weight\n",
       "alice         1985       NaN   Biking      68\n",
       "bob           1984         3  Dancing      83\n",
       "charles       1992         0      NaN     112"
      ]
     },
     "execution_count": 73,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "people"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 74,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>hobby</th>\n",
       "      <th>weight</th>\n",
       "      <th>age</th>\n",
       "      <th>over 30</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>alice</th>\n",
       "      <td>Biking</td>\n",
       "      <td>68</td>\n",
       "      <td>31</td>\n",
       "      <td>True</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>bob</th>\n",
       "      <td>Dancing</td>\n",
       "      <td>83</td>\n",
       "      <td>32</td>\n",
       "      <td>True</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>charles</th>\n",
       "      <td>NaN</td>\n",
       "      <td>112</td>\n",
       "      <td>24</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "           hobby  weight  age over 30\n",
       "alice     Biking      68   31    True\n",
       "bob      Dancing      83   32    True\n",
       "charles      NaN     112   24   False"
      ]
     },
     "execution_count": 74,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "people[\"age\"] = 2016 - people[\"birthyear\"]  # adds a new column \"age\"\n",
    "people[\"over 30\"] = people[\"age\"] > 30      # adds another column \"over 30\"\n",
    "birthyears = people.pop(\"birthyear\")\n",
    "del people[\"children\"]\n",
    "\n",
    "people"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 75,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "alice      1985\n",
       "bob        1984\n",
       "charles    1992\n",
       "Name: birthyear, dtype: int64"
      ]
     },
     "execution_count": 75,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "birthyears"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "When you add a new colum, it must have the same number of rows. Missing rows are filled with NaN, and extra rows are ignored:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 76,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>hobby</th>\n",
       "      <th>weight</th>\n",
       "      <th>age</th>\n",
       "      <th>over 30</th>\n",
       "      <th>pets</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>alice</th>\n",
       "      <td>Biking</td>\n",
       "      <td>68</td>\n",
       "      <td>31</td>\n",
       "      <td>True</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>bob</th>\n",
       "      <td>Dancing</td>\n",
       "      <td>83</td>\n",
       "      <td>32</td>\n",
       "      <td>True</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>charles</th>\n",
       "      <td>NaN</td>\n",
       "      <td>112</td>\n",
       "      <td>24</td>\n",
       "      <td>False</td>\n",
       "      <td>5</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "           hobby  weight  age over 30  pets\n",
       "alice     Biking      68   31    True   NaN\n",
       "bob      Dancing      83   32    True     0\n",
       "charles      NaN     112   24   False     5"
      ]
     },
     "execution_count": 76,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "people[\"pets\"] = pd.Series({\"bob\": 0, \"charles\": 5, \"eugene\":1})  # alice is missing, eugene is ignored\n",
    "people"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "When adding a new column, it is added at the end (on the right) by default. You can also insert a column anywhere else using the `insert` method:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 77,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>hobby</th>\n",
       "      <th>height</th>\n",
       "      <th>weight</th>\n",
       "      <th>age</th>\n",
       "      <th>over 30</th>\n",
       "      <th>pets</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>alice</th>\n",
       "      <td>Biking</td>\n",
       "      <td>172</td>\n",
       "      <td>68</td>\n",
       "      <td>31</td>\n",
       "      <td>True</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>bob</th>\n",
       "      <td>Dancing</td>\n",
       "      <td>181</td>\n",
       "      <td>83</td>\n",
       "      <td>32</td>\n",
       "      <td>True</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>charles</th>\n",
       "      <td>NaN</td>\n",
       "      <td>185</td>\n",
       "      <td>112</td>\n",
       "      <td>24</td>\n",
       "      <td>False</td>\n",
       "      <td>5</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "           hobby  height  weight  age over 30  pets\n",
       "alice     Biking     172      68   31    True   NaN\n",
       "bob      Dancing     181      83   32    True     0\n",
       "charles      NaN     185     112   24   False     5"
      ]
     },
     "execution_count": 77,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "people.insert(1, \"height\", [172, 181, 185])\n",
    "people"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Assigning new columns\n",
    "You can also create new columns by calling the `assign` method. Note that this returns a new `DataFrame` object, the original is not modified:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 78,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>hobby</th>\n",
       "      <th>height</th>\n",
       "      <th>weight</th>\n",
       "      <th>age</th>\n",
       "      <th>over 30</th>\n",
       "      <th>pets</th>\n",
       "      <th>body_mass_index</th>\n",
       "      <th>has_pets</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>alice</th>\n",
       "      <td>Biking</td>\n",
       "      <td>172</td>\n",
       "      <td>68</td>\n",
       "      <td>31</td>\n",
       "      <td>True</td>\n",
       "      <td>NaN</td>\n",
       "      <td>22.985398</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>bob</th>\n",
       "      <td>Dancing</td>\n",
       "      <td>181</td>\n",
       "      <td>83</td>\n",
       "      <td>32</td>\n",
       "      <td>True</td>\n",
       "      <td>0</td>\n",
       "      <td>25.335002</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>charles</th>\n",
       "      <td>NaN</td>\n",
       "      <td>185</td>\n",
       "      <td>112</td>\n",
       "      <td>24</td>\n",
       "      <td>False</td>\n",
       "      <td>5</td>\n",
       "      <td>32.724617</td>\n",
       "      <td>True</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "           hobby  height  weight  age over 30  pets  body_mass_index has_pets\n",
       "alice     Biking     172      68   31    True   NaN        22.985398    False\n",
       "bob      Dancing     181      83   32    True     0        25.335002    False\n",
       "charles      NaN     185     112   24   False     5        32.724617     True"
      ]
     },
     "execution_count": 78,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "people.assign(\n",
    "    body_mass_index = people[\"weight\"] / (people[\"height\"] / 100) ** 2,\n",
    "    has_pets = people[\"pets\"] > 0\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Note that you cannot access columns created within the same assignment:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 79,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Key error: u'body_mass_index'\n"
     ]
    }
   ],
   "source": [
    "try:\n",
    "    people.assign(\n",
    "        body_mass_index = people[\"weight\"] / (people[\"height\"] / 100) ** 2,\n",
    "        overweight = people[\"body_mass_index\"] > 25\n",
    "    )\n",
    "except KeyError as e:\n",
    "    print(\"Key error:\", e)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The solution is to split this assignment in two consecutive assignments:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 80,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>hobby</th>\n",
       "      <th>height</th>\n",
       "      <th>weight</th>\n",
       "      <th>age</th>\n",
       "      <th>over 30</th>\n",
       "      <th>pets</th>\n",
       "      <th>body_mass_index</th>\n",
       "      <th>overweight</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>alice</th>\n",
       "      <td>Biking</td>\n",
       "      <td>172</td>\n",
       "      <td>68</td>\n",
       "      <td>31</td>\n",
       "      <td>True</td>\n",
       "      <td>NaN</td>\n",
       "      <td>22.985398</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>bob</th>\n",
       "      <td>Dancing</td>\n",
       "      <td>181</td>\n",
       "      <td>83</td>\n",
       "      <td>32</td>\n",
       "      <td>True</td>\n",
       "      <td>0</td>\n",
       "      <td>25.335002</td>\n",
       "      <td>True</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>charles</th>\n",
       "      <td>NaN</td>\n",
       "      <td>185</td>\n",
       "      <td>112</td>\n",
       "      <td>24</td>\n",
       "      <td>False</td>\n",
       "      <td>5</td>\n",
       "      <td>32.724617</td>\n",
       "      <td>True</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "           hobby  height  weight  age over 30  pets  body_mass_index  \\\n",
       "alice     Biking     172      68   31    True   NaN        22.985398   \n",
       "bob      Dancing     181      83   32    True     0        25.335002   \n",
       "charles      NaN     185     112   24   False     5        32.724617   \n",
       "\n",
       "        overweight  \n",
       "alice        False  \n",
       "bob           True  \n",
       "charles       True  "
      ]
     },
     "execution_count": 80,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "d6 = people.assign(body_mass_index = people[\"weight\"] / (people[\"height\"] / 100) ** 2)\n",
    "d6.assign(overweight = d6[\"body_mass_index\"] > 25)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Having to create a temporary variable `d6` is not very convenient. You may want to just chain the assigment calls, but it does not work because the `people` object is not actually modified by the first assignment:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 81,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Key error: u'body_mass_index'\n"
     ]
    }
   ],
   "source": [
    "try:\n",
    "    (people\n",
    "         .assign(body_mass_index = people[\"weight\"] / (people[\"height\"] / 100) ** 2)\n",
    "         .assign(overweight = people[\"body_mass_index\"] > 25)\n",
    "    )\n",
    "except KeyError as e:\n",
    "    print(\"Key error:\", e)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "But fear not, there is a simple solution. You can pass a function to the `assign` method (typically a `lambda` function), and this function will be called with the `DataFrame` as a parameter:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 82,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>hobby</th>\n",
       "      <th>height</th>\n",
       "      <th>weight</th>\n",
       "      <th>age</th>\n",
       "      <th>over 30</th>\n",
       "      <th>pets</th>\n",
       "      <th>body_mass_index</th>\n",
       "      <th>overweight</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>alice</th>\n",
       "      <td>Biking</td>\n",
       "      <td>172</td>\n",
       "      <td>68</td>\n",
       "      <td>31</td>\n",
       "      <td>True</td>\n",
       "      <td>NaN</td>\n",
       "      <td>22.985398</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>bob</th>\n",
       "      <td>Dancing</td>\n",
       "      <td>181</td>\n",
       "      <td>83</td>\n",
       "      <td>32</td>\n",
       "      <td>True</td>\n",
       "      <td>0</td>\n",
       "      <td>25.335002</td>\n",
       "      <td>True</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>charles</th>\n",
       "      <td>NaN</td>\n",
       "      <td>185</td>\n",
       "      <td>112</td>\n",
       "      <td>24</td>\n",
       "      <td>False</td>\n",
       "      <td>5</td>\n",
       "      <td>32.724617</td>\n",
       "      <td>True</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "           hobby  height  weight  age over 30  pets  body_mass_index  \\\n",
       "alice     Biking     172      68   31    True   NaN        22.985398   \n",
       "bob      Dancing     181      83   32    True     0        25.335002   \n",
       "charles      NaN     185     112   24   False     5        32.724617   \n",
       "\n",
       "        overweight  \n",
       "alice        False  \n",
       "bob           True  \n",
       "charles       True  "
      ]
     },
     "execution_count": 82,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "(people\n",
    "     .assign(body_mass_index = lambda df: df[\"weight\"] / (df[\"height\"] / 100) ** 2)\n",
    "     .assign(overweight = lambda df: df[\"body_mass_index\"] > 25)\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Problem solved!"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Evaluating an expression\n",
    "A great feature supported by pandas is expression evaluation. This relies on the `numexpr` library which must be installed."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 83,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "alice      False\n",
       "bob         True\n",
       "charles     True\n",
       "dtype: bool"
      ]
     },
     "execution_count": 83,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "people.eval(\"weight / (height/100) ** 2 > 25\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Assignment expressions are also supported, and contrary to the `assign` method, this does not create a copy of the `DataFrame`, instead it directly modifies it:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 84,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>hobby</th>\n",
       "      <th>height</th>\n",
       "      <th>weight</th>\n",
       "      <th>age</th>\n",
       "      <th>over 30</th>\n",
       "      <th>pets</th>\n",
       "      <th>body_mass_index</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>alice</th>\n",
       "      <td>Biking</td>\n",
       "      <td>172</td>\n",
       "      <td>68</td>\n",
       "      <td>31</td>\n",
       "      <td>True</td>\n",
       "      <td>NaN</td>\n",
       "      <td>22.985398</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>bob</th>\n",
       "      <td>Dancing</td>\n",
       "      <td>181</td>\n",
       "      <td>83</td>\n",
       "      <td>32</td>\n",
       "      <td>True</td>\n",
       "      <td>0</td>\n",
       "      <td>25.335002</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>charles</th>\n",
       "      <td>NaN</td>\n",
       "      <td>185</td>\n",
       "      <td>112</td>\n",
       "      <td>24</td>\n",
       "      <td>False</td>\n",
       "      <td>5</td>\n",
       "      <td>32.724617</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "           hobby  height  weight  age over 30  pets  body_mass_index\n",
       "alice     Biking     172      68   31    True   NaN        22.985398\n",
       "bob      Dancing     181      83   32    True     0        25.335002\n",
       "charles      NaN     185     112   24   False     5        32.724617"
      ]
     },
     "execution_count": 84,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "people.eval(\"body_mass_index = weight / (height/100) ** 2\")\n",
    "people"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can use a local or global variable in an expression by prefixing it with `'@'`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 85,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>hobby</th>\n",
       "      <th>height</th>\n",
       "      <th>weight</th>\n",
       "      <th>age</th>\n",
       "      <th>over 30</th>\n",
       "      <th>pets</th>\n",
       "      <th>body_mass_index</th>\n",
       "      <th>overweight</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>alice</th>\n",
       "      <td>Biking</td>\n",
       "      <td>172</td>\n",
       "      <td>68</td>\n",
       "      <td>31</td>\n",
       "      <td>True</td>\n",
       "      <td>NaN</td>\n",
       "      <td>22.985398</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>bob</th>\n",
       "      <td>Dancing</td>\n",
       "      <td>181</td>\n",
       "      <td>83</td>\n",
       "      <td>32</td>\n",
       "      <td>True</td>\n",
       "      <td>0</td>\n",
       "      <td>25.335002</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>charles</th>\n",
       "      <td>NaN</td>\n",
       "      <td>185</td>\n",
       "      <td>112</td>\n",
       "      <td>24</td>\n",
       "      <td>False</td>\n",
       "      <td>5</td>\n",
       "      <td>32.724617</td>\n",
       "      <td>True</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "           hobby  height  weight  age over 30  pets  body_mass_index  \\\n",
       "alice     Biking     172      68   31    True   NaN        22.985398   \n",
       "bob      Dancing     181      83   32    True     0        25.335002   \n",
       "charles      NaN     185     112   24   False     5        32.724617   \n",
       "\n",
       "        overweight  \n",
       "alice        False  \n",
       "bob          False  \n",
       "charles       True  "
      ]
     },
     "execution_count": 85,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "overweight_threshold = 30\n",
    "people.eval(\"overweight = body_mass_index > @overweight_threshold\")\n",
    "people"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Querying a `DataFrame`\n",
    "The `query` method lets you filter a `DataFrame` based on a query expression:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 86,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>hobby</th>\n",
       "      <th>height</th>\n",
       "      <th>weight</th>\n",
       "      <th>age</th>\n",
       "      <th>over 30</th>\n",
       "      <th>pets</th>\n",
       "      <th>body_mass_index</th>\n",
       "      <th>overweight</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>bob</th>\n",
       "      <td>Dancing</td>\n",
       "      <td>181</td>\n",
       "      <td>83</td>\n",
       "      <td>32</td>\n",
       "      <td>True</td>\n",
       "      <td>0</td>\n",
       "      <td>25.335002</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "       hobby  height  weight  age over 30  pets  body_mass_index overweight\n",
       "bob  Dancing     181      83   32    True     0        25.335002      False"
      ]
     },
     "execution_count": 86,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "people.query(\"age > 30 and pets == 0\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Sorting a `DataFrame`\n",
    "You can sort a `DataFrame` by calling its `sort_index` method. By default it sorts the rows by their index label, in ascending order, but let's reverse the order:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 87,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>hobby</th>\n",
       "      <th>height</th>\n",
       "      <th>weight</th>\n",
       "      <th>age</th>\n",
       "      <th>over 30</th>\n",
       "      <th>pets</th>\n",
       "      <th>body_mass_index</th>\n",
       "      <th>overweight</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>charles</th>\n",
       "      <td>NaN</td>\n",
       "      <td>185</td>\n",
       "      <td>112</td>\n",
       "      <td>24</td>\n",
       "      <td>False</td>\n",
       "      <td>5</td>\n",
       "      <td>32.724617</td>\n",
       "      <td>True</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>bob</th>\n",
       "      <td>Dancing</td>\n",
       "      <td>181</td>\n",
       "      <td>83</td>\n",
       "      <td>32</td>\n",
       "      <td>True</td>\n",
       "      <td>0</td>\n",
       "      <td>25.335002</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>alice</th>\n",
       "      <td>Biking</td>\n",
       "      <td>172</td>\n",
       "      <td>68</td>\n",
       "      <td>31</td>\n",
       "      <td>True</td>\n",
       "      <td>NaN</td>\n",
       "      <td>22.985398</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "           hobby  height  weight  age over 30  pets  body_mass_index  \\\n",
       "charles      NaN     185     112   24   False     5        32.724617   \n",
       "bob      Dancing     181      83   32    True     0        25.335002   \n",
       "alice     Biking     172      68   31    True   NaN        22.985398   \n",
       "\n",
       "        overweight  \n",
       "charles       True  \n",
       "bob          False  \n",
       "alice        False  "
      ]
     },
     "execution_count": 87,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "people.sort_index(ascending=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Note that `sort_index` returned a sorted *copy* of the `DataFrame`. To modify `people` directly, we can set the `inplace` argument to `True`. Also, we can sort the columns instead of the rows by setting `axis=1`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 88,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>age</th>\n",
       "      <th>body_mass_index</th>\n",
       "      <th>height</th>\n",
       "      <th>hobby</th>\n",
       "      <th>over 30</th>\n",
       "      <th>overweight</th>\n",
       "      <th>pets</th>\n",
       "      <th>weight</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>alice</th>\n",
       "      <td>31</td>\n",
       "      <td>22.985398</td>\n",
       "      <td>172</td>\n",
       "      <td>Biking</td>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "      <td>NaN</td>\n",
       "      <td>68</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>bob</th>\n",
       "      <td>32</td>\n",
       "      <td>25.335002</td>\n",
       "      <td>181</td>\n",
       "      <td>Dancing</td>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "      <td>0</td>\n",
       "      <td>83</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>charles</th>\n",
       "      <td>24</td>\n",
       "      <td>32.724617</td>\n",
       "      <td>185</td>\n",
       "      <td>NaN</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "      <td>5</td>\n",
       "      <td>112</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "         age  body_mass_index  height    hobby over 30 overweight  pets  \\\n",
       "alice     31        22.985398     172   Biking    True      False   NaN   \n",
       "bob       32        25.335002     181  Dancing    True      False     0   \n",
       "charles   24        32.724617     185      NaN   False       True     5   \n",
       "\n",
       "         weight  \n",
       "alice        68  \n",
       "bob          83  \n",
       "charles     112  "
      ]
     },
     "execution_count": 88,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "people.sort_index(axis=1, inplace=True)\n",
    "people"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To sort the `DataFrame` by the values instead of the labels, we can use `sort_values` and specify the column to sort by:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 89,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>age</th>\n",
       "      <th>body_mass_index</th>\n",
       "      <th>height</th>\n",
       "      <th>hobby</th>\n",
       "      <th>over 30</th>\n",
       "      <th>overweight</th>\n",
       "      <th>pets</th>\n",
       "      <th>weight</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>charles</th>\n",
       "      <td>24</td>\n",
       "      <td>32.724617</td>\n",
       "      <td>185</td>\n",
       "      <td>NaN</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "      <td>5</td>\n",
       "      <td>112</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>alice</th>\n",
       "      <td>31</td>\n",
       "      <td>22.985398</td>\n",
       "      <td>172</td>\n",
       "      <td>Biking</td>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "      <td>NaN</td>\n",
       "      <td>68</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>bob</th>\n",
       "      <td>32</td>\n",
       "      <td>25.335002</td>\n",
       "      <td>181</td>\n",
       "      <td>Dancing</td>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "      <td>0</td>\n",
       "      <td>83</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "         age  body_mass_index  height    hobby over 30 overweight  pets  \\\n",
       "charles   24        32.724617     185      NaN   False       True     5   \n",
       "alice     31        22.985398     172   Biking    True      False   NaN   \n",
       "bob       32        25.335002     181  Dancing    True      False     0   \n",
       "\n",
       "         weight  \n",
       "charles     112  \n",
       "alice        68  \n",
       "bob          83  "
      ]
     },
     "execution_count": 89,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "people.sort_values(by=\"age\", inplace=True)\n",
    "people"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Plotting a `DataFrame`\n",
    "Just like for `Series`, pandas makes it easy to draw nice graphs based on a `DataFrame`.\n",
    "\n",
    "For example, it is trivial to create a line plot from a `DataFrame`'s data by calling its `plot` method:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 90,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x10c1b49d0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "people.plot(kind = \"line\", x = \"body_mass_index\", y = [\"height\", \"weight\"])\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can pass extra arguments supported by matplotlib's functions. For example, we can create scatterplot and pass it a list of sizes using the `s` argument of matplotlib's `scatter` function:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 91,
   "metadata": {
    "collapsed": false,
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x10c277850>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "people.plot(kind = \"scatter\", x = \"height\", y = \"weight\", s=[40, 120, 200])\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Again, there are way too many options to list here: the best option is to scroll through the [Visualization](http://pandas.pydata.org/pandas-docs/stable/visualization.html) page in pandas' documentation, find the plot you are interested in and look at the example code."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Operations on `DataFrame`s\n",
    "Although `DataFrame`s do not try to mimick NumPy arrays, there are a few similarities. Let's create a `DataFrame` to demonstrate this:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 92,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>sep</th>\n",
       "      <th>oct</th>\n",
       "      <th>nov</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>alice</th>\n",
       "      <td>8</td>\n",
       "      <td>8</td>\n",
       "      <td>9</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>bob</th>\n",
       "      <td>10</td>\n",
       "      <td>9</td>\n",
       "      <td>9</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>charles</th>\n",
       "      <td>4</td>\n",
       "      <td>8</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>darwin</th>\n",
       "      <td>9</td>\n",
       "      <td>10</td>\n",
       "      <td>10</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "         sep  oct  nov\n",
       "alice      8    8    9\n",
       "bob       10    9    9\n",
       "charles    4    8    2\n",
       "darwin     9   10   10"
      ]
     },
     "execution_count": 92,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "grades_array = np.array([[8,8,9],[10,9,9],[4, 8, 2], [9, 10, 10]])\n",
    "grades = pd.DataFrame(grades_array, columns=[\"sep\", \"oct\", \"nov\"], index=[\"alice\",\"bob\",\"charles\",\"darwin\"])\n",
    "grades"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can apply NumPy mathematical functions on a `DataFrame`: the function is applied to all values:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 93,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>sep</th>\n",
       "      <th>oct</th>\n",
       "      <th>nov</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>alice</th>\n",
       "      <td>2.828427</td>\n",
       "      <td>2.828427</td>\n",
       "      <td>3.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>bob</th>\n",
       "      <td>3.162278</td>\n",
       "      <td>3.000000</td>\n",
       "      <td>3.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>charles</th>\n",
       "      <td>2.000000</td>\n",
       "      <td>2.828427</td>\n",
       "      <td>1.414214</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>darwin</th>\n",
       "      <td>3.000000</td>\n",
       "      <td>3.162278</td>\n",
       "      <td>3.162278</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "              sep       oct       nov\n",
       "alice    2.828427  2.828427  3.000000\n",
       "bob      3.162278  3.000000  3.000000\n",
       "charles  2.000000  2.828427  1.414214\n",
       "darwin   3.000000  3.162278  3.162278"
      ]
     },
     "execution_count": 93,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.sqrt(grades)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Similarly, adding a single value to a `DataFrame` will add that value to all elements in the `DataFrame`. This is called *broadcasting*:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 94,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>sep</th>\n",
       "      <th>oct</th>\n",
       "      <th>nov</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>alice</th>\n",
       "      <td>9</td>\n",
       "      <td>9</td>\n",
       "      <td>10</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>bob</th>\n",
       "      <td>11</td>\n",
       "      <td>10</td>\n",
       "      <td>10</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>charles</th>\n",
       "      <td>5</td>\n",
       "      <td>9</td>\n",
       "      <td>3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>darwin</th>\n",
       "      <td>10</td>\n",
       "      <td>11</td>\n",
       "      <td>11</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "         sep  oct  nov\n",
       "alice      9    9   10\n",
       "bob       11   10   10\n",
       "charles    5    9    3\n",
       "darwin    10   11   11"
      ]
     },
     "execution_count": 94,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "grades + 1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Of course, the same is true for all other binary operations, including arithmetic (`*`,`/`,`**`...) and conditional (`>`, `==`...) operations:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 95,
   "metadata": {
    "collapsed": false,
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>sep</th>\n",
       "      <th>oct</th>\n",
       "      <th>nov</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>alice</th>\n",
       "      <td>True</td>\n",
       "      <td>True</td>\n",
       "      <td>True</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>bob</th>\n",
       "      <td>True</td>\n",
       "      <td>True</td>\n",
       "      <td>True</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>charles</th>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>darwin</th>\n",
       "      <td>True</td>\n",
       "      <td>True</td>\n",
       "      <td>True</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "           sep   oct    nov\n",
       "alice     True  True   True\n",
       "bob       True  True   True\n",
       "charles  False  True  False\n",
       "darwin    True  True   True"
      ]
     },
     "execution_count": 95,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "grades >= 5"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Aggregation operations, such as computing the `max`, the `sum` or the `mean` of a `DataFrame`, apply to each column, and you get back a `Series` object:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 96,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "sep    7.75\n",
       "oct    8.75\n",
       "nov    7.50\n",
       "dtype: float64"
      ]
     },
     "execution_count": 96,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "grades.mean()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The `all` method is also an aggregation operation: it checks whether all values are `True` or not. Let's see during which months all students got a grade greater than `5`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 97,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "sep    False\n",
       "oct     True\n",
       "nov    False\n",
       "dtype: bool"
      ]
     },
     "execution_count": 97,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "(grades > 5).all()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Most of these functions take an optional `axis` parameter which lets you specify along which axis of the `DataFrame` you want the operation executed. The default is `axis=0`, meaning that the operation is executed vertically (on each column). You can set `axis=1` to execute the operation horizontally (on each row). For example, let's find out which students had all grades greater than `5`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 98,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "alice       True\n",
       "bob         True\n",
       "charles    False\n",
       "darwin      True\n",
       "dtype: bool"
      ]
     },
     "execution_count": 98,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "(grades > 5).all(axis = 1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The `any` method returns `True` if any value is True. Let's see who got at least one grade 10:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 99,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "alice      False\n",
       "bob         True\n",
       "charles    False\n",
       "darwin      True\n",
       "dtype: bool"
      ]
     },
     "execution_count": 99,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "(grades == 10).any(axis = 1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If you add a `Series` object to a `DataFrame` (or execute any other binary operation), pandas attempts to broadcast the operation to all *rows* in the `DataFrame`. This only works if the `Series` has the same size as the `DataFrame`s rows. For example, let's substract the `mean` of the `DataFrame` (a `Series` object) from the `DataFrame`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 100,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>sep</th>\n",
       "      <th>oct</th>\n",
       "      <th>nov</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>alice</th>\n",
       "      <td>0.25</td>\n",
       "      <td>-0.75</td>\n",
       "      <td>1.5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>bob</th>\n",
       "      <td>2.25</td>\n",
       "      <td>0.25</td>\n",
       "      <td>1.5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>charles</th>\n",
       "      <td>-3.75</td>\n",
       "      <td>-0.75</td>\n",
       "      <td>-5.5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>darwin</th>\n",
       "      <td>1.25</td>\n",
       "      <td>1.25</td>\n",
       "      <td>2.5</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "          sep   oct  nov\n",
       "alice    0.25 -0.75  1.5\n",
       "bob      2.25  0.25  1.5\n",
       "charles -3.75 -0.75 -5.5\n",
       "darwin   1.25  1.25  2.5"
      ]
     },
     "execution_count": 100,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "grades - grades.mean()  # equivalent to: grades - [7.75, 8.75, 7.50]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We substracted `7.75` from all September grades, `8.75` from October grades and `7.50` from November grades. It is equivalent to substracting this `DataFrame`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 101,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>sep</th>\n",
       "      <th>oct</th>\n",
       "      <th>nov</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>alice</th>\n",
       "      <td>7.75</td>\n",
       "      <td>8.75</td>\n",
       "      <td>7.5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>bob</th>\n",
       "      <td>7.75</td>\n",
       "      <td>8.75</td>\n",
       "      <td>7.5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>charles</th>\n",
       "      <td>7.75</td>\n",
       "      <td>8.75</td>\n",
       "      <td>7.5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>darwin</th>\n",
       "      <td>7.75</td>\n",
       "      <td>8.75</td>\n",
       "      <td>7.5</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "          sep   oct  nov\n",
       "alice    7.75  8.75  7.5\n",
       "bob      7.75  8.75  7.5\n",
       "charles  7.75  8.75  7.5\n",
       "darwin   7.75  8.75  7.5"
      ]
     },
     "execution_count": 101,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.DataFrame([[7.75, 8.75, 7.50]]*4, index=grades.index, columns=grades.columns)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If you want to substract the global mean from every grade, here is one way to do it:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 102,
   "metadata": {
    "collapsed": false,
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>sep</th>\n",
       "      <th>oct</th>\n",
       "      <th>nov</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>alice</th>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>bob</th>\n",
       "      <td>2</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>charles</th>\n",
       "      <td>-4</td>\n",
       "      <td>0</td>\n",
       "      <td>-6</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>darwin</th>\n",
       "      <td>1</td>\n",
       "      <td>2</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "         sep  oct  nov\n",
       "alice      0    0    1\n",
       "bob        2    1    1\n",
       "charles   -4    0   -6\n",
       "darwin     1    2    2"
      ]
     },
     "execution_count": 102,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "grades - grades.values.mean() # substracts the global mean (8.00) from all grades"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Automatic alignment\n",
    "Similar to `Series`, when operating on multiple `DataFrame`s, pandas automatically aligns them by row index label, but also by column names. Let's create a `DataFrame` with bonus points for each person from October to December:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 103,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>oct</th>\n",
       "      <th>nov</th>\n",
       "      <th>dec</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>bob</th>\n",
       "      <td>0</td>\n",
       "      <td>NaN</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>colin</th>\n",
       "      <td>NaN</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>darwin</th>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>charles</th>\n",
       "      <td>3</td>\n",
       "      <td>3</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "         oct  nov  dec\n",
       "bob        0  NaN    2\n",
       "colin    NaN    1    0\n",
       "darwin     0    1    0\n",
       "charles    3    3    0"
      ]
     },
     "execution_count": 103,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "bonus_array = np.array([[0,np.nan,2],[np.nan,1,0],[0, 1, 0], [3, 3, 0]])\n",
    "bonus_points = pd.DataFrame(bonus_array, columns=[\"oct\", \"nov\", \"dec\"], index=[\"bob\",\"colin\", \"darwin\", \"charles\"])\n",
    "bonus_points"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 104,
   "metadata": {
    "collapsed": false,
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>dec</th>\n",
       "      <th>nov</th>\n",
       "      <th>oct</th>\n",
       "      <th>sep</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>alice</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>bob</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>9</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>charles</th>\n",
       "      <td>NaN</td>\n",
       "      <td>5</td>\n",
       "      <td>11</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>colin</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>darwin</th>\n",
       "      <td>NaN</td>\n",
       "      <td>11</td>\n",
       "      <td>10</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "         dec  nov  oct  sep\n",
       "alice    NaN  NaN  NaN  NaN\n",
       "bob      NaN  NaN    9  NaN\n",
       "charles  NaN    5   11  NaN\n",
       "colin    NaN  NaN  NaN  NaN\n",
       "darwin   NaN   11   10  NaN"
      ]
     },
     "execution_count": 104,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "grades + bonus_points"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Looks like the addition worked in some cases but way too many elements are now empty. That's because when aligning the `DataFrame`s, some columns and rows were only present on one side, and thus they were considered missing on the other side (`NaN`). Then adding `NaN` to a number results in `NaN`, hence the result.\n",
    "\n",
    "## Handling missing data\n",
    "Dealing with missing data is a frequent task when working with real life data. Pandas offers a few tools to handle missing data.\n",
    " \n",
    "Let's try to fix the problem above. For example, we can decide that missing data should result in a zero, instead of `NaN`. We can replace all `NaN` values by a any value using the `fillna` method:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 105,
   "metadata": {
    "collapsed": false,
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>dec</th>\n",
       "      <th>nov</th>\n",
       "      <th>oct</th>\n",
       "      <th>sep</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>alice</th>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>bob</th>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>9</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>charles</th>\n",
       "      <td>0</td>\n",
       "      <td>5</td>\n",
       "      <td>11</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>colin</th>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>darwin</th>\n",
       "      <td>0</td>\n",
       "      <td>11</td>\n",
       "      <td>10</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "         dec  nov  oct  sep\n",
       "alice      0    0    0    0\n",
       "bob        0    0    9    0\n",
       "charles    0    5   11    0\n",
       "colin      0    0    0    0\n",
       "darwin     0   11   10    0"
      ]
     },
     "execution_count": 105,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "(grades + bonus_points).fillna(0)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "It's a bit unfair that we're setting grades to zero in September, though. Perhaps we should decide that missing grades are missing grades, but missing bonus points should be replaced by zeros:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 106,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>dec</th>\n",
       "      <th>nov</th>\n",
       "      <th>oct</th>\n",
       "      <th>sep</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>alice</th>\n",
       "      <td>NaN</td>\n",
       "      <td>9</td>\n",
       "      <td>8</td>\n",
       "      <td>8</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>bob</th>\n",
       "      <td>NaN</td>\n",
       "      <td>9</td>\n",
       "      <td>9</td>\n",
       "      <td>10</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>charles</th>\n",
       "      <td>NaN</td>\n",
       "      <td>5</td>\n",
       "      <td>11</td>\n",
       "      <td>4</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>colin</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>darwin</th>\n",
       "      <td>NaN</td>\n",
       "      <td>11</td>\n",
       "      <td>10</td>\n",
       "      <td>9</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "         dec  nov  oct  sep\n",
       "alice    NaN    9    8    8\n",
       "bob      NaN    9    9   10\n",
       "charles  NaN    5   11    4\n",
       "colin    NaN  NaN  NaN  NaN\n",
       "darwin   NaN   11   10    9"
      ]
     },
     "execution_count": 106,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "fixed_bonus_points = bonus_points.fillna(0)\n",
    "fixed_bonus_points.insert(0, \"sep\", 0)\n",
    "fixed_bonus_points.loc[\"alice\"] = 0\n",
    "grades + fixed_bonus_points"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "That's much better: although we made up some data, we have not been too unfair.\n",
    "\n",
    "Another way to handle missing data is to interpolate. Let's look at the `bonus_points` `DataFrame` again:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 107,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>oct</th>\n",
       "      <th>nov</th>\n",
       "      <th>dec</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>bob</th>\n",
       "      <td>0</td>\n",
       "      <td>NaN</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>colin</th>\n",
       "      <td>NaN</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>darwin</th>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>charles</th>\n",
       "      <td>3</td>\n",
       "      <td>3</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "         oct  nov  dec\n",
       "bob        0  NaN    2\n",
       "colin    NaN    1    0\n",
       "darwin     0    1    0\n",
       "charles    3    3    0"
      ]
     },
     "execution_count": 107,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "bonus_points"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now let's call the `interpolate` method. By default, it interpolates vertically (`axis=0`), so let's tell it to interpolate horizontally (`axis=1`)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 108,
   "metadata": {
    "collapsed": false,
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>oct</th>\n",
       "      <th>nov</th>\n",
       "      <th>dec</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>bob</th>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>colin</th>\n",
       "      <td>NaN</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>darwin</th>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>charles</th>\n",
       "      <td>3</td>\n",
       "      <td>3</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "         oct  nov  dec\n",
       "bob        0    1    2\n",
       "colin    NaN    1    0\n",
       "darwin     0    1    0\n",
       "charles    3    3    0"
      ]
     },
     "execution_count": 108,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "bonus_points.interpolate(axis=1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Bob had 0 bonus points in October, and 2 in December. When we interpolate for November, we get the mean: 1 bonus point. Colin had 1 bonus point in November, but we do not know how many bonus points he had in September, so we cannot interpolate, this is why there is still a missing value in October after interpolation. To fix this, we can set the September bonus points to 0 before interpolation."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 109,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>sep</th>\n",
       "      <th>oct</th>\n",
       "      <th>nov</th>\n",
       "      <th>dec</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>bob</th>\n",
       "      <td>0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>1</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>colin</th>\n",
       "      <td>0</td>\n",
       "      <td>0.5</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>darwin</th>\n",
       "      <td>0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>charles</th>\n",
       "      <td>0</td>\n",
       "      <td>3.0</td>\n",
       "      <td>3</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>alice</th>\n",
       "      <td>0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "         sep  oct  nov  dec\n",
       "bob        0  0.0    1    2\n",
       "colin      0  0.5    1    0\n",
       "darwin     0  0.0    1    0\n",
       "charles    0  3.0    3    0\n",
       "alice      0  0.0    0    0"
      ]
     },
     "execution_count": 109,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "better_bonus_points = bonus_points.copy()\n",
    "better_bonus_points.insert(0, \"sep\", 0)\n",
    "better_bonus_points.loc[\"alice\"] = 0\n",
    "better_bonus_points = better_bonus_points.interpolate(axis=1)\n",
    "better_bonus_points"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Great, now we have reasonable bonus points everywhere. Let's find out the final grades:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 110,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>dec</th>\n",
       "      <th>nov</th>\n",
       "      <th>oct</th>\n",
       "      <th>sep</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>alice</th>\n",
       "      <td>NaN</td>\n",
       "      <td>9</td>\n",
       "      <td>8</td>\n",
       "      <td>8</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>bob</th>\n",
       "      <td>NaN</td>\n",
       "      <td>10</td>\n",
       "      <td>9</td>\n",
       "      <td>10</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>charles</th>\n",
       "      <td>NaN</td>\n",
       "      <td>5</td>\n",
       "      <td>11</td>\n",
       "      <td>4</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>colin</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>darwin</th>\n",
       "      <td>NaN</td>\n",
       "      <td>11</td>\n",
       "      <td>10</td>\n",
       "      <td>9</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "         dec  nov  oct  sep\n",
       "alice    NaN    9    8    8\n",
       "bob      NaN   10    9   10\n",
       "charles  NaN    5   11    4\n",
       "colin    NaN  NaN  NaN  NaN\n",
       "darwin   NaN   11   10    9"
      ]
     },
     "execution_count": 110,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "grades + better_bonus_points"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "It is slightly annoying that the September column ends up on the right. This is because the `DataFrame`s we are adding do not have the exact same columns (the `grades` `DataFrame` is missing the `\"dec\"` column), so to make things predictable, pandas orders the final columns alphabetically. To fix this, we can simply add the missing column before adding:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 111,
   "metadata": {
    "collapsed": false,
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>sep</th>\n",
       "      <th>oct</th>\n",
       "      <th>nov</th>\n",
       "      <th>dec</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>alice</th>\n",
       "      <td>8</td>\n",
       "      <td>8</td>\n",
       "      <td>9</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>bob</th>\n",
       "      <td>10</td>\n",
       "      <td>9</td>\n",
       "      <td>10</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>charles</th>\n",
       "      <td>4</td>\n",
       "      <td>11</td>\n",
       "      <td>5</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>colin</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>darwin</th>\n",
       "      <td>9</td>\n",
       "      <td>10</td>\n",
       "      <td>11</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "         sep  oct  nov  dec\n",
       "alice      8    8    9  NaN\n",
       "bob       10    9   10  NaN\n",
       "charles    4   11    5  NaN\n",
       "colin    NaN  NaN  NaN  NaN\n",
       "darwin     9   10   11  NaN"
      ]
     },
     "execution_count": 111,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "grades[\"dec\"] = np.nan\n",
    "final_grades = grades + better_bonus_points\n",
    "final_grades"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "There's not much we can do about December and Colin: it's bad enough that we are making up bonus points, but we can't reasonably make up grades (well I guess some teachers probably do). So let's call the `dropna` method to get rid of rows that are full of `NaN`s:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 112,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>sep</th>\n",
       "      <th>oct</th>\n",
       "      <th>nov</th>\n",
       "      <th>dec</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>alice</th>\n",
       "      <td>8</td>\n",
       "      <td>8</td>\n",
       "      <td>9</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>bob</th>\n",
       "      <td>10</td>\n",
       "      <td>9</td>\n",
       "      <td>10</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>charles</th>\n",
       "      <td>4</td>\n",
       "      <td>11</td>\n",
       "      <td>5</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>darwin</th>\n",
       "      <td>9</td>\n",
       "      <td>10</td>\n",
       "      <td>11</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "         sep  oct  nov  dec\n",
       "alice      8    8    9  NaN\n",
       "bob       10    9   10  NaN\n",
       "charles    4   11    5  NaN\n",
       "darwin     9   10   11  NaN"
      ]
     },
     "execution_count": 112,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "final_grades_clean = final_grades.dropna(how=\"all\")\n",
    "final_grades_clean"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now let's remove columns that are full of `NaN`s by setting the `axis` argument to `1`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 113,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>sep</th>\n",
       "      <th>oct</th>\n",
       "      <th>nov</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>alice</th>\n",
       "      <td>8</td>\n",
       "      <td>8</td>\n",
       "      <td>9</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>bob</th>\n",
       "      <td>10</td>\n",
       "      <td>9</td>\n",
       "      <td>10</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>charles</th>\n",
       "      <td>4</td>\n",
       "      <td>11</td>\n",
       "      <td>5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>darwin</th>\n",
       "      <td>9</td>\n",
       "      <td>10</td>\n",
       "      <td>11</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "         sep  oct  nov\n",
       "alice      8    8    9\n",
       "bob       10    9   10\n",
       "charles    4   11    5\n",
       "darwin     9   10   11"
      ]
     },
     "execution_count": 113,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "final_grades_clean = final_grades_clean.dropna(axis=1, how=\"all\")\n",
    "final_grades_clean"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Aggregating with `groupby`\n",
    "Similar to the SQL language, pandas allows grouping your data into groups to run calculations over each group.\n",
    "\n",
    "First, let's add some extra data about each person so we can group them, and let's go back to the `final_grades` `DataFrame` so we can see how `NaN` values are handled:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 114,
   "metadata": {
    "collapsed": false,
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>sep</th>\n",
       "      <th>oct</th>\n",
       "      <th>nov</th>\n",
       "      <th>dec</th>\n",
       "      <th>hobby</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>alice</th>\n",
       "      <td>8</td>\n",
       "      <td>8</td>\n",
       "      <td>9</td>\n",
       "      <td>NaN</td>\n",
       "      <td>Biking</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>bob</th>\n",
       "      <td>10</td>\n",
       "      <td>9</td>\n",
       "      <td>10</td>\n",
       "      <td>NaN</td>\n",
       "      <td>Dancing</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>charles</th>\n",
       "      <td>4</td>\n",
       "      <td>11</td>\n",
       "      <td>5</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>colin</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>Dancing</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>darwin</th>\n",
       "      <td>9</td>\n",
       "      <td>10</td>\n",
       "      <td>11</td>\n",
       "      <td>NaN</td>\n",
       "      <td>Biking</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "         sep  oct  nov  dec    hobby\n",
       "alice      8    8    9  NaN   Biking\n",
       "bob       10    9   10  NaN  Dancing\n",
       "charles    4   11    5  NaN      NaN\n",
       "colin    NaN  NaN  NaN  NaN  Dancing\n",
       "darwin     9   10   11  NaN   Biking"
      ]
     },
     "execution_count": 114,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "final_grades[\"hobby\"] = [\"Biking\", \"Dancing\", np.nan, \"Dancing\", \"Biking\"]\n",
    "final_grades"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now let's group data in this `DataFrame` by hobby:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 115,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<pandas.core.groupby.DataFrameGroupBy object at 0x10c3ab410>"
      ]
     },
     "execution_count": 115,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "grouped_grades = final_grades.groupby(\"hobby\")\n",
    "grouped_grades"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We are ready to compute the average grade per hobby:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 116,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>sep</th>\n",
       "      <th>oct</th>\n",
       "      <th>nov</th>\n",
       "      <th>dec</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>hobby</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>Biking</th>\n",
       "      <td>8.5</td>\n",
       "      <td>9</td>\n",
       "      <td>10</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Dancing</th>\n",
       "      <td>10.0</td>\n",
       "      <td>9</td>\n",
       "      <td>10</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "          sep  oct  nov  dec\n",
       "hobby                       \n",
       "Biking    8.5    9   10  NaN\n",
       "Dancing  10.0    9   10  NaN"
      ]
     },
     "execution_count": 116,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "grouped_grades.mean()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "That was easy! Note that the `NaN` values have simply been skipped when computing the means."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Pivot tables\n",
    "Pandas supports spreadsheet-like [pivot tables](https://en.wikipedia.org/wiki/Pivot_table) that allow quick data summarization. To illustrate this, let's create a simple `DataFrame`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 117,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>oct</th>\n",
       "      <th>nov</th>\n",
       "      <th>dec</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>bob</th>\n",
       "      <td>0</td>\n",
       "      <td>NaN</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>colin</th>\n",
       "      <td>NaN</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>darwin</th>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>charles</th>\n",
       "      <td>3</td>\n",
       "      <td>3</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "         oct  nov  dec\n",
       "bob        0  NaN    2\n",
       "colin    NaN    1    0\n",
       "darwin     0    1    0\n",
       "charles    3    3    0"
      ]
     },
     "execution_count": 117,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "bonus_points"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 118,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>name</th>\n",
       "      <th>month</th>\n",
       "      <th>grade</th>\n",
       "      <th>bonus</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>alice</td>\n",
       "      <td>sep</td>\n",
       "      <td>8</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>alice</td>\n",
       "      <td>oct</td>\n",
       "      <td>8</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>alice</td>\n",
       "      <td>nov</td>\n",
       "      <td>9</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>bob</td>\n",
       "      <td>sep</td>\n",
       "      <td>10</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>bob</td>\n",
       "      <td>oct</td>\n",
       "      <td>9</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>bob</td>\n",
       "      <td>nov</td>\n",
       "      <td>10</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>charles</td>\n",
       "      <td>sep</td>\n",
       "      <td>4</td>\n",
       "      <td>3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>charles</td>\n",
       "      <td>oct</td>\n",
       "      <td>11</td>\n",
       "      <td>3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>charles</td>\n",
       "      <td>nov</td>\n",
       "      <td>5</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>darwin</td>\n",
       "      <td>sep</td>\n",
       "      <td>9</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10</th>\n",
       "      <td>darwin</td>\n",
       "      <td>oct</td>\n",
       "      <td>10</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>11</th>\n",
       "      <td>darwin</td>\n",
       "      <td>nov</td>\n",
       "      <td>11</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "       name month  grade  bonus\n",
       "0     alice   sep      8    NaN\n",
       "1     alice   oct      8    NaN\n",
       "2     alice   nov      9    NaN\n",
       "3       bob   sep     10      0\n",
       "4       bob   oct      9    NaN\n",
       "5       bob   nov     10      2\n",
       "6   charles   sep      4      3\n",
       "7   charles   oct     11      3\n",
       "8   charles   nov      5      0\n",
       "9    darwin   sep      9      0\n",
       "10   darwin   oct     10      1\n",
       "11   darwin   nov     11      0"
      ]
     },
     "execution_count": 118,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "more_grades = final_grades_clean.stack().reset_index()\n",
    "more_grades.columns = [\"name\", \"month\", \"grade\"]\n",
    "more_grades[\"bonus\"] = [np.nan, np.nan, np.nan, 0, np.nan, 2, 3, 3, 0, 0, 1, 0]\n",
    "more_grades"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now we can call the `pivot_table` function for this `DataFrame`, asking to group by the `name` column. By default, `pivot_table` computes the `mean` of each numeric column:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 119,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>bonus</th>\n",
       "      <th>grade</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>name</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>alice</th>\n",
       "      <td>NaN</td>\n",
       "      <td>8.333333</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>bob</th>\n",
       "      <td>1.000000</td>\n",
       "      <td>9.666667</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>charles</th>\n",
       "      <td>2.000000</td>\n",
       "      <td>6.666667</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>darwin</th>\n",
       "      <td>0.333333</td>\n",
       "      <td>10.000000</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "            bonus      grade\n",
       "name                        \n",
       "alice         NaN   8.333333\n",
       "bob      1.000000   9.666667\n",
       "charles  2.000000   6.666667\n",
       "darwin   0.333333  10.000000"
      ]
     },
     "execution_count": 119,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.pivot_table(more_grades, index=\"name\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can change the aggregation function by setting the `aggfunc` attribute, and we can also specify the list of columns whose values will be aggregated:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 120,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>bonus</th>\n",
       "      <th>grade</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>name</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>alice</th>\n",
       "      <td>NaN</td>\n",
       "      <td>9</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>bob</th>\n",
       "      <td>2</td>\n",
       "      <td>10</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>charles</th>\n",
       "      <td>3</td>\n",
       "      <td>11</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>darwin</th>\n",
       "      <td>1</td>\n",
       "      <td>11</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "         bonus  grade\n",
       "name                 \n",
       "alice      NaN      9\n",
       "bob          2     10\n",
       "charles      3     11\n",
       "darwin       1     11"
      ]
     },
     "execution_count": 120,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.pivot_table(more_grades, index=\"name\", values=[\"grade\",\"bonus\"], aggfunc=np.max)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can also specify the `columns` to aggregate over horizontally, and request the grand totals for each row and column by setting `margins=True`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 121,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th>month</th>\n",
       "      <th>nov</th>\n",
       "      <th>oct</th>\n",
       "      <th>sep</th>\n",
       "      <th>All</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>name</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>alice</th>\n",
       "      <td>9.00</td>\n",
       "      <td>8.0</td>\n",
       "      <td>8.00</td>\n",
       "      <td>8.333333</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>bob</th>\n",
       "      <td>10.00</td>\n",
       "      <td>9.0</td>\n",
       "      <td>10.00</td>\n",
       "      <td>9.666667</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>charles</th>\n",
       "      <td>5.00</td>\n",
       "      <td>11.0</td>\n",
       "      <td>4.00</td>\n",
       "      <td>6.666667</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>darwin</th>\n",
       "      <td>11.00</td>\n",
       "      <td>10.0</td>\n",
       "      <td>9.00</td>\n",
       "      <td>10.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>All</th>\n",
       "      <td>8.75</td>\n",
       "      <td>9.5</td>\n",
       "      <td>7.75</td>\n",
       "      <td>8.666667</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "month      nov   oct    sep        All\n",
       "name                                  \n",
       "alice     9.00   8.0   8.00   8.333333\n",
       "bob      10.00   9.0  10.00   9.666667\n",
       "charles   5.00  11.0   4.00   6.666667\n",
       "darwin   11.00  10.0   9.00  10.000000\n",
       "All       8.75   9.5   7.75   8.666667"
      ]
     },
     "execution_count": 121,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.pivot_table(more_grades, index=\"name\", values=\"grade\", columns=\"month\", margins=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Finally, we can specify multiple index or column names, and pandas will create multi-level indices:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 122,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>bonus</th>\n",
       "      <th>grade</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>name</th>\n",
       "      <th>month</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th rowspan=\"3\" valign=\"top\">alice</th>\n",
       "      <th>nov</th>\n",
       "      <td>NaN</td>\n",
       "      <td>9.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>oct</th>\n",
       "      <td>NaN</td>\n",
       "      <td>8.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>sep</th>\n",
       "      <td>NaN</td>\n",
       "      <td>8.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"3\" valign=\"top\">bob</th>\n",
       "      <th>nov</th>\n",
       "      <td>2.000</td>\n",
       "      <td>10.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>oct</th>\n",
       "      <td>NaN</td>\n",
       "      <td>9.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>sep</th>\n",
       "      <td>0.000</td>\n",
       "      <td>10.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"3\" valign=\"top\">charles</th>\n",
       "      <th>nov</th>\n",
       "      <td>0.000</td>\n",
       "      <td>5.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>oct</th>\n",
       "      <td>3.000</td>\n",
       "      <td>11.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>sep</th>\n",
       "      <td>3.000</td>\n",
       "      <td>4.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"3\" valign=\"top\">darwin</th>\n",
       "      <th>nov</th>\n",
       "      <td>0.000</td>\n",
       "      <td>11.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>oct</th>\n",
       "      <td>1.000</td>\n",
       "      <td>10.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>sep</th>\n",
       "      <td>0.000</td>\n",
       "      <td>9.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>All</th>\n",
       "      <th></th>\n",
       "      <td>1.125</td>\n",
       "      <td>8.666667</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "               bonus      grade\n",
       "name    month                  \n",
       "alice   nov      NaN   9.000000\n",
       "        oct      NaN   8.000000\n",
       "        sep      NaN   8.000000\n",
       "bob     nov    2.000  10.000000\n",
       "        oct      NaN   9.000000\n",
       "        sep    0.000  10.000000\n",
       "charles nov    0.000   5.000000\n",
       "        oct    3.000  11.000000\n",
       "        sep    3.000   4.000000\n",
       "darwin  nov    0.000  11.000000\n",
       "        oct    1.000  10.000000\n",
       "        sep    0.000   9.000000\n",
       "All            1.125   8.666667"
      ]
     },
     "execution_count": 122,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.pivot_table(more_grades, index=(\"name\", \"month\"), margins=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Overview functions\n",
    "When dealing with large `DataFrames`, it is useful to get a quick overview of its content. Pandas offers a few functions for this. First, let's create a large `DataFrame` with a mix of numeric values, missing values and text values. Notice how Jupyter displays only the corners of the `DataFrame`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 123,
   "metadata": {
    "collapsed": false,
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>A</th>\n",
       "      <th>B</th>\n",
       "      <th>C</th>\n",
       "      <th>some_text</th>\n",
       "      <th>D</th>\n",
       "      <th>E</th>\n",
       "      <th>F</th>\n",
       "      <th>G</th>\n",
       "      <th>H</th>\n",
       "      <th>I</th>\n",
       "      <th>...</th>\n",
       "      <th>Q</th>\n",
       "      <th>R</th>\n",
       "      <th>S</th>\n",
       "      <th>T</th>\n",
       "      <th>U</th>\n",
       "      <th>V</th>\n",
       "      <th>W</th>\n",
       "      <th>X</th>\n",
       "      <th>Y</th>\n",
       "      <th>Z</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>NaN</td>\n",
       "      <td>11</td>\n",
       "      <td>44</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>99</td>\n",
       "      <td>NaN</td>\n",
       "      <td>88</td>\n",
       "      <td>22</td>\n",
       "      <td>165</td>\n",
       "      <td>143</td>\n",
       "      <td>...</td>\n",
       "      <td>11</td>\n",
       "      <td>NaN</td>\n",
       "      <td>11</td>\n",
       "      <td>44</td>\n",
       "      <td>99</td>\n",
       "      <td>NaN</td>\n",
       "      <td>88</td>\n",
       "      <td>22</td>\n",
       "      <td>165</td>\n",
       "      <td>143</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>11</td>\n",
       "      <td>22</td>\n",
       "      <td>55</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>110</td>\n",
       "      <td>NaN</td>\n",
       "      <td>99</td>\n",
       "      <td>33</td>\n",
       "      <td>NaN</td>\n",
       "      <td>154</td>\n",
       "      <td>...</td>\n",
       "      <td>22</td>\n",
       "      <td>11</td>\n",
       "      <td>22</td>\n",
       "      <td>55</td>\n",
       "      <td>110</td>\n",
       "      <td>NaN</td>\n",
       "      <td>99</td>\n",
       "      <td>33</td>\n",
       "      <td>NaN</td>\n",
       "      <td>154</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>22</td>\n",
       "      <td>33</td>\n",
       "      <td>66</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>121</td>\n",
       "      <td>11</td>\n",
       "      <td>110</td>\n",
       "      <td>44</td>\n",
       "      <td>NaN</td>\n",
       "      <td>165</td>\n",
       "      <td>...</td>\n",
       "      <td>33</td>\n",
       "      <td>22</td>\n",
       "      <td>33</td>\n",
       "      <td>66</td>\n",
       "      <td>121</td>\n",
       "      <td>11</td>\n",
       "      <td>110</td>\n",
       "      <td>44</td>\n",
       "      <td>NaN</td>\n",
       "      <td>165</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>33</td>\n",
       "      <td>44</td>\n",
       "      <td>77</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>132</td>\n",
       "      <td>22</td>\n",
       "      <td>121</td>\n",
       "      <td>55</td>\n",
       "      <td>11</td>\n",
       "      <td>NaN</td>\n",
       "      <td>...</td>\n",
       "      <td>44</td>\n",
       "      <td>33</td>\n",
       "      <td>44</td>\n",
       "      <td>77</td>\n",
       "      <td>132</td>\n",
       "      <td>22</td>\n",
       "      <td>121</td>\n",
       "      <td>55</td>\n",
       "      <td>11</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>44</td>\n",
       "      <td>55</td>\n",
       "      <td>88</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>143</td>\n",
       "      <td>33</td>\n",
       "      <td>132</td>\n",
       "      <td>66</td>\n",
       "      <td>22</td>\n",
       "      <td>NaN</td>\n",
       "      <td>...</td>\n",
       "      <td>55</td>\n",
       "      <td>44</td>\n",
       "      <td>55</td>\n",
       "      <td>88</td>\n",
       "      <td>143</td>\n",
       "      <td>33</td>\n",
       "      <td>132</td>\n",
       "      <td>66</td>\n",
       "      <td>22</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>55</td>\n",
       "      <td>66</td>\n",
       "      <td>99</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>154</td>\n",
       "      <td>44</td>\n",
       "      <td>143</td>\n",
       "      <td>77</td>\n",
       "      <td>33</td>\n",
       "      <td>11</td>\n",
       "      <td>...</td>\n",
       "      <td>66</td>\n",
       "      <td>55</td>\n",
       "      <td>66</td>\n",
       "      <td>99</td>\n",
       "      <td>154</td>\n",
       "      <td>44</td>\n",
       "      <td>143</td>\n",
       "      <td>77</td>\n",
       "      <td>33</td>\n",
       "      <td>11</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>66</td>\n",
       "      <td>77</td>\n",
       "      <td>110</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>165</td>\n",
       "      <td>55</td>\n",
       "      <td>154</td>\n",
       "      <td>88</td>\n",
       "      <td>44</td>\n",
       "      <td>22</td>\n",
       "      <td>...</td>\n",
       "      <td>77</td>\n",
       "      <td>66</td>\n",
       "      <td>77</td>\n",
       "      <td>110</td>\n",
       "      <td>165</td>\n",
       "      <td>55</td>\n",
       "      <td>154</td>\n",
       "      <td>88</td>\n",
       "      <td>44</td>\n",
       "      <td>22</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>77</td>\n",
       "      <td>88</td>\n",
       "      <td>121</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>NaN</td>\n",
       "      <td>66</td>\n",
       "      <td>165</td>\n",
       "      <td>99</td>\n",
       "      <td>55</td>\n",
       "      <td>33</td>\n",
       "      <td>...</td>\n",
       "      <td>88</td>\n",
       "      <td>77</td>\n",
       "      <td>88</td>\n",
       "      <td>121</td>\n",
       "      <td>NaN</td>\n",
       "      <td>66</td>\n",
       "      <td>165</td>\n",
       "      <td>99</td>\n",
       "      <td>55</td>\n",
       "      <td>33</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>88</td>\n",
       "      <td>99</td>\n",
       "      <td>132</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>NaN</td>\n",
       "      <td>77</td>\n",
       "      <td>NaN</td>\n",
       "      <td>110</td>\n",
       "      <td>66</td>\n",
       "      <td>44</td>\n",
       "      <td>...</td>\n",
       "      <td>99</td>\n",
       "      <td>88</td>\n",
       "      <td>99</td>\n",
       "      <td>132</td>\n",
       "      <td>NaN</td>\n",
       "      <td>77</td>\n",
       "      <td>NaN</td>\n",
       "      <td>110</td>\n",
       "      <td>66</td>\n",
       "      <td>44</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>99</td>\n",
       "      <td>110</td>\n",
       "      <td>143</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>11</td>\n",
       "      <td>88</td>\n",
       "      <td>NaN</td>\n",
       "      <td>121</td>\n",
       "      <td>77</td>\n",
       "      <td>55</td>\n",
       "      <td>...</td>\n",
       "      <td>110</td>\n",
       "      <td>99</td>\n",
       "      <td>110</td>\n",
       "      <td>143</td>\n",
       "      <td>11</td>\n",
       "      <td>88</td>\n",
       "      <td>NaN</td>\n",
       "      <td>121</td>\n",
       "      <td>77</td>\n",
       "      <td>55</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10</th>\n",
       "      <td>110</td>\n",
       "      <td>121</td>\n",
       "      <td>154</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>22</td>\n",
       "      <td>99</td>\n",
       "      <td>11</td>\n",
       "      <td>132</td>\n",
       "      <td>88</td>\n",
       "      <td>66</td>\n",
       "      <td>...</td>\n",
       "      <td>121</td>\n",
       "      <td>110</td>\n",
       "      <td>121</td>\n",
       "      <td>154</td>\n",
       "      <td>22</td>\n",
       "      <td>99</td>\n",
       "      <td>11</td>\n",
       "      <td>132</td>\n",
       "      <td>88</td>\n",
       "      <td>66</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>11</th>\n",
       "      <td>121</td>\n",
       "      <td>132</td>\n",
       "      <td>165</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>33</td>\n",
       "      <td>110</td>\n",
       "      <td>22</td>\n",
       "      <td>143</td>\n",
       "      <td>99</td>\n",
       "      <td>77</td>\n",
       "      <td>...</td>\n",
       "      <td>132</td>\n",
       "      <td>121</td>\n",
       "      <td>132</td>\n",
       "      <td>165</td>\n",
       "      <td>33</td>\n",
       "      <td>110</td>\n",
       "      <td>22</td>\n",
       "      <td>143</td>\n",
       "      <td>99</td>\n",
       "      <td>77</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>12</th>\n",
       "      <td>132</td>\n",
       "      <td>143</td>\n",
       "      <td>NaN</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>44</td>\n",
       "      <td>121</td>\n",
       "      <td>33</td>\n",
       "      <td>154</td>\n",
       "      <td>110</td>\n",
       "      <td>88</td>\n",
       "      <td>...</td>\n",
       "      <td>143</td>\n",
       "      <td>132</td>\n",
       "      <td>143</td>\n",
       "      <td>NaN</td>\n",
       "      <td>44</td>\n",
       "      <td>121</td>\n",
       "      <td>33</td>\n",
       "      <td>154</td>\n",
       "      <td>110</td>\n",
       "      <td>88</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>13</th>\n",
       "      <td>143</td>\n",
       "      <td>154</td>\n",
       "      <td>NaN</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>55</td>\n",
       "      <td>132</td>\n",
       "      <td>44</td>\n",
       "      <td>165</td>\n",
       "      <td>121</td>\n",
       "      <td>99</td>\n",
       "      <td>...</td>\n",
       "      <td>154</td>\n",
       "      <td>143</td>\n",
       "      <td>154</td>\n",
       "      <td>NaN</td>\n",
       "      <td>55</td>\n",
       "      <td>132</td>\n",
       "      <td>44</td>\n",
       "      <td>165</td>\n",
       "      <td>121</td>\n",
       "      <td>99</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>14</th>\n",
       "      <td>154</td>\n",
       "      <td>165</td>\n",
       "      <td>11</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>66</td>\n",
       "      <td>143</td>\n",
       "      <td>55</td>\n",
       "      <td>NaN</td>\n",
       "      <td>132</td>\n",
       "      <td>110</td>\n",
       "      <td>...</td>\n",
       "      <td>165</td>\n",
       "      <td>154</td>\n",
       "      <td>165</td>\n",
       "      <td>11</td>\n",
       "      <td>66</td>\n",
       "      <td>143</td>\n",
       "      <td>55</td>\n",
       "      <td>NaN</td>\n",
       "      <td>132</td>\n",
       "      <td>110</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>15</th>\n",
       "      <td>165</td>\n",
       "      <td>NaN</td>\n",
       "      <td>22</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>77</td>\n",
       "      <td>154</td>\n",
       "      <td>66</td>\n",
       "      <td>NaN</td>\n",
       "      <td>143</td>\n",
       "      <td>121</td>\n",
       "      <td>...</td>\n",
       "      <td>NaN</td>\n",
       "      <td>165</td>\n",
       "      <td>NaN</td>\n",
       "      <td>22</td>\n",
       "      <td>77</td>\n",
       "      <td>154</td>\n",
       "      <td>66</td>\n",
       "      <td>NaN</td>\n",
       "      <td>143</td>\n",
       "      <td>121</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>16</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>33</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>88</td>\n",
       "      <td>165</td>\n",
       "      <td>77</td>\n",
       "      <td>11</td>\n",
       "      <td>154</td>\n",
       "      <td>132</td>\n",
       "      <td>...</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>33</td>\n",
       "      <td>88</td>\n",
       "      <td>165</td>\n",
       "      <td>77</td>\n",
       "      <td>11</td>\n",
       "      <td>154</td>\n",
       "      <td>132</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>17</th>\n",
       "      <td>NaN</td>\n",
       "      <td>11</td>\n",
       "      <td>44</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>99</td>\n",
       "      <td>NaN</td>\n",
       "      <td>88</td>\n",
       "      <td>22</td>\n",
       "      <td>165</td>\n",
       "      <td>143</td>\n",
       "      <td>...</td>\n",
       "      <td>11</td>\n",
       "      <td>NaN</td>\n",
       "      <td>11</td>\n",
       "      <td>44</td>\n",
       "      <td>99</td>\n",
       "      <td>NaN</td>\n",
       "      <td>88</td>\n",
       "      <td>22</td>\n",
       "      <td>165</td>\n",
       "      <td>143</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>18</th>\n",
       "      <td>11</td>\n",
       "      <td>22</td>\n",
       "      <td>55</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>110</td>\n",
       "      <td>NaN</td>\n",
       "      <td>99</td>\n",
       "      <td>33</td>\n",
       "      <td>NaN</td>\n",
       "      <td>154</td>\n",
       "      <td>...</td>\n",
       "      <td>22</td>\n",
       "      <td>11</td>\n",
       "      <td>22</td>\n",
       "      <td>55</td>\n",
       "      <td>110</td>\n",
       "      <td>NaN</td>\n",
       "      <td>99</td>\n",
       "      <td>33</td>\n",
       "      <td>NaN</td>\n",
       "      <td>154</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>19</th>\n",
       "      <td>22</td>\n",
       "      <td>33</td>\n",
       "      <td>66</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>121</td>\n",
       "      <td>11</td>\n",
       "      <td>110</td>\n",
       "      <td>44</td>\n",
       "      <td>NaN</td>\n",
       "      <td>165</td>\n",
       "      <td>...</td>\n",
       "      <td>33</td>\n",
       "      <td>22</td>\n",
       "      <td>33</td>\n",
       "      <td>66</td>\n",
       "      <td>121</td>\n",
       "      <td>11</td>\n",
       "      <td>110</td>\n",
       "      <td>44</td>\n",
       "      <td>NaN</td>\n",
       "      <td>165</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>20</th>\n",
       "      <td>33</td>\n",
       "      <td>44</td>\n",
       "      <td>77</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>132</td>\n",
       "      <td>22</td>\n",
       "      <td>121</td>\n",
       "      <td>55</td>\n",
       "      <td>11</td>\n",
       "      <td>NaN</td>\n",
       "      <td>...</td>\n",
       "      <td>44</td>\n",
       "      <td>33</td>\n",
       "      <td>44</td>\n",
       "      <td>77</td>\n",
       "      <td>132</td>\n",
       "      <td>22</td>\n",
       "      <td>121</td>\n",
       "      <td>55</td>\n",
       "      <td>11</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>21</th>\n",
       "      <td>44</td>\n",
       "      <td>55</td>\n",
       "      <td>88</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>143</td>\n",
       "      <td>33</td>\n",
       "      <td>132</td>\n",
       "      <td>66</td>\n",
       "      <td>22</td>\n",
       "      <td>NaN</td>\n",
       "      <td>...</td>\n",
       "      <td>55</td>\n",
       "      <td>44</td>\n",
       "      <td>55</td>\n",
       "      <td>88</td>\n",
       "      <td>143</td>\n",
       "      <td>33</td>\n",
       "      <td>132</td>\n",
       "      <td>66</td>\n",
       "      <td>22</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>22</th>\n",
       "      <td>55</td>\n",
       "      <td>66</td>\n",
       "      <td>99</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>154</td>\n",
       "      <td>44</td>\n",
       "      <td>143</td>\n",
       "      <td>77</td>\n",
       "      <td>33</td>\n",
       "      <td>11</td>\n",
       "      <td>...</td>\n",
       "      <td>66</td>\n",
       "      <td>55</td>\n",
       "      <td>66</td>\n",
       "      <td>99</td>\n",
       "      <td>154</td>\n",
       "      <td>44</td>\n",
       "      <td>143</td>\n",
       "      <td>77</td>\n",
       "      <td>33</td>\n",
       "      <td>11</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>23</th>\n",
       "      <td>66</td>\n",
       "      <td>77</td>\n",
       "      <td>110</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>165</td>\n",
       "      <td>55</td>\n",
       "      <td>154</td>\n",
       "      <td>88</td>\n",
       "      <td>44</td>\n",
       "      <td>22</td>\n",
       "      <td>...</td>\n",
       "      <td>77</td>\n",
       "      <td>66</td>\n",
       "      <td>77</td>\n",
       "      <td>110</td>\n",
       "      <td>165</td>\n",
       "      <td>55</td>\n",
       "      <td>154</td>\n",
       "      <td>88</td>\n",
       "      <td>44</td>\n",
       "      <td>22</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>24</th>\n",
       "      <td>77</td>\n",
       "      <td>88</td>\n",
       "      <td>121</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>NaN</td>\n",
       "      <td>66</td>\n",
       "      <td>165</td>\n",
       "      <td>99</td>\n",
       "      <td>55</td>\n",
       "      <td>33</td>\n",
       "      <td>...</td>\n",
       "      <td>88</td>\n",
       "      <td>77</td>\n",
       "      <td>88</td>\n",
       "      <td>121</td>\n",
       "      <td>NaN</td>\n",
       "      <td>66</td>\n",
       "      <td>165</td>\n",
       "      <td>99</td>\n",
       "      <td>55</td>\n",
       "      <td>33</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>25</th>\n",
       "      <td>88</td>\n",
       "      <td>99</td>\n",
       "      <td>132</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>NaN</td>\n",
       "      <td>77</td>\n",
       "      <td>NaN</td>\n",
       "      <td>110</td>\n",
       "      <td>66</td>\n",
       "      <td>44</td>\n",
       "      <td>...</td>\n",
       "      <td>99</td>\n",
       "      <td>88</td>\n",
       "      <td>99</td>\n",
       "      <td>132</td>\n",
       "      <td>NaN</td>\n",
       "      <td>77</td>\n",
       "      <td>NaN</td>\n",
       "      <td>110</td>\n",
       "      <td>66</td>\n",
       "      <td>44</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>26</th>\n",
       "      <td>99</td>\n",
       "      <td>110</td>\n",
       "      <td>143</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>11</td>\n",
       "      <td>88</td>\n",
       "      <td>NaN</td>\n",
       "      <td>121</td>\n",
       "      <td>77</td>\n",
       "      <td>55</td>\n",
       "      <td>...</td>\n",
       "      <td>110</td>\n",
       "      <td>99</td>\n",
       "      <td>110</td>\n",
       "      <td>143</td>\n",
       "      <td>11</td>\n",
       "      <td>88</td>\n",
       "      <td>NaN</td>\n",
       "      <td>121</td>\n",
       "      <td>77</td>\n",
       "      <td>55</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>27</th>\n",
       "      <td>110</td>\n",
       "      <td>121</td>\n",
       "      <td>154</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>22</td>\n",
       "      <td>99</td>\n",
       "      <td>11</td>\n",
       "      <td>132</td>\n",
       "      <td>88</td>\n",
       "      <td>66</td>\n",
       "      <td>...</td>\n",
       "      <td>121</td>\n",
       "      <td>110</td>\n",
       "      <td>121</td>\n",
       "      <td>154</td>\n",
       "      <td>22</td>\n",
       "      <td>99</td>\n",
       "      <td>11</td>\n",
       "      <td>132</td>\n",
       "      <td>88</td>\n",
       "      <td>66</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>28</th>\n",
       "      <td>121</td>\n",
       "      <td>132</td>\n",
       "      <td>165</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>33</td>\n",
       "      <td>110</td>\n",
       "      <td>22</td>\n",
       "      <td>143</td>\n",
       "      <td>99</td>\n",
       "      <td>77</td>\n",
       "      <td>...</td>\n",
       "      <td>132</td>\n",
       "      <td>121</td>\n",
       "      <td>132</td>\n",
       "      <td>165</td>\n",
       "      <td>33</td>\n",
       "      <td>110</td>\n",
       "      <td>22</td>\n",
       "      <td>143</td>\n",
       "      <td>99</td>\n",
       "      <td>77</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>29</th>\n",
       "      <td>132</td>\n",
       "      <td>143</td>\n",
       "      <td>NaN</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>44</td>\n",
       "      <td>121</td>\n",
       "      <td>33</td>\n",
       "      <td>154</td>\n",
       "      <td>110</td>\n",
       "      <td>88</td>\n",
       "      <td>...</td>\n",
       "      <td>143</td>\n",
       "      <td>132</td>\n",
       "      <td>143</td>\n",
       "      <td>NaN</td>\n",
       "      <td>44</td>\n",
       "      <td>121</td>\n",
       "      <td>33</td>\n",
       "      <td>154</td>\n",
       "      <td>110</td>\n",
       "      <td>88</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9970</th>\n",
       "      <td>88</td>\n",
       "      <td>99</td>\n",
       "      <td>132</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>NaN</td>\n",
       "      <td>77</td>\n",
       "      <td>NaN</td>\n",
       "      <td>110</td>\n",
       "      <td>66</td>\n",
       "      <td>44</td>\n",
       "      <td>...</td>\n",
       "      <td>99</td>\n",
       "      <td>88</td>\n",
       "      <td>99</td>\n",
       "      <td>132</td>\n",
       "      <td>NaN</td>\n",
       "      <td>77</td>\n",
       "      <td>NaN</td>\n",
       "      <td>110</td>\n",
       "      <td>66</td>\n",
       "      <td>44</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9971</th>\n",
       "      <td>99</td>\n",
       "      <td>110</td>\n",
       "      <td>143</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>11</td>\n",
       "      <td>88</td>\n",
       "      <td>NaN</td>\n",
       "      <td>121</td>\n",
       "      <td>77</td>\n",
       "      <td>55</td>\n",
       "      <td>...</td>\n",
       "      <td>110</td>\n",
       "      <td>99</td>\n",
       "      <td>110</td>\n",
       "      <td>143</td>\n",
       "      <td>11</td>\n",
       "      <td>88</td>\n",
       "      <td>NaN</td>\n",
       "      <td>121</td>\n",
       "      <td>77</td>\n",
       "      <td>55</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9972</th>\n",
       "      <td>110</td>\n",
       "      <td>121</td>\n",
       "      <td>154</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>22</td>\n",
       "      <td>99</td>\n",
       "      <td>11</td>\n",
       "      <td>132</td>\n",
       "      <td>88</td>\n",
       "      <td>66</td>\n",
       "      <td>...</td>\n",
       "      <td>121</td>\n",
       "      <td>110</td>\n",
       "      <td>121</td>\n",
       "      <td>154</td>\n",
       "      <td>22</td>\n",
       "      <td>99</td>\n",
       "      <td>11</td>\n",
       "      <td>132</td>\n",
       "      <td>88</td>\n",
       "      <td>66</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9973</th>\n",
       "      <td>121</td>\n",
       "      <td>132</td>\n",
       "      <td>165</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>33</td>\n",
       "      <td>110</td>\n",
       "      <td>22</td>\n",
       "      <td>143</td>\n",
       "      <td>99</td>\n",
       "      <td>77</td>\n",
       "      <td>...</td>\n",
       "      <td>132</td>\n",
       "      <td>121</td>\n",
       "      <td>132</td>\n",
       "      <td>165</td>\n",
       "      <td>33</td>\n",
       "      <td>110</td>\n",
       "      <td>22</td>\n",
       "      <td>143</td>\n",
       "      <td>99</td>\n",
       "      <td>77</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9974</th>\n",
       "      <td>132</td>\n",
       "      <td>143</td>\n",
       "      <td>NaN</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>44</td>\n",
       "      <td>121</td>\n",
       "      <td>33</td>\n",
       "      <td>154</td>\n",
       "      <td>110</td>\n",
       "      <td>88</td>\n",
       "      <td>...</td>\n",
       "      <td>143</td>\n",
       "      <td>132</td>\n",
       "      <td>143</td>\n",
       "      <td>NaN</td>\n",
       "      <td>44</td>\n",
       "      <td>121</td>\n",
       "      <td>33</td>\n",
       "      <td>154</td>\n",
       "      <td>110</td>\n",
       "      <td>88</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9975</th>\n",
       "      <td>143</td>\n",
       "      <td>154</td>\n",
       "      <td>NaN</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>55</td>\n",
       "      <td>132</td>\n",
       "      <td>44</td>\n",
       "      <td>165</td>\n",
       "      <td>121</td>\n",
       "      <td>99</td>\n",
       "      <td>...</td>\n",
       "      <td>154</td>\n",
       "      <td>143</td>\n",
       "      <td>154</td>\n",
       "      <td>NaN</td>\n",
       "      <td>55</td>\n",
       "      <td>132</td>\n",
       "      <td>44</td>\n",
       "      <td>165</td>\n",
       "      <td>121</td>\n",
       "      <td>99</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9976</th>\n",
       "      <td>154</td>\n",
       "      <td>165</td>\n",
       "      <td>11</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>66</td>\n",
       "      <td>143</td>\n",
       "      <td>55</td>\n",
       "      <td>NaN</td>\n",
       "      <td>132</td>\n",
       "      <td>110</td>\n",
       "      <td>...</td>\n",
       "      <td>165</td>\n",
       "      <td>154</td>\n",
       "      <td>165</td>\n",
       "      <td>11</td>\n",
       "      <td>66</td>\n",
       "      <td>143</td>\n",
       "      <td>55</td>\n",
       "      <td>NaN</td>\n",
       "      <td>132</td>\n",
       "      <td>110</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9977</th>\n",
       "      <td>165</td>\n",
       "      <td>NaN</td>\n",
       "      <td>22</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>77</td>\n",
       "      <td>154</td>\n",
       "      <td>66</td>\n",
       "      <td>NaN</td>\n",
       "      <td>143</td>\n",
       "      <td>121</td>\n",
       "      <td>...</td>\n",
       "      <td>NaN</td>\n",
       "      <td>165</td>\n",
       "      <td>NaN</td>\n",
       "      <td>22</td>\n",
       "      <td>77</td>\n",
       "      <td>154</td>\n",
       "      <td>66</td>\n",
       "      <td>NaN</td>\n",
       "      <td>143</td>\n",
       "      <td>121</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9978</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>33</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>88</td>\n",
       "      <td>165</td>\n",
       "      <td>77</td>\n",
       "      <td>11</td>\n",
       "      <td>154</td>\n",
       "      <td>132</td>\n",
       "      <td>...</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>33</td>\n",
       "      <td>88</td>\n",
       "      <td>165</td>\n",
       "      <td>77</td>\n",
       "      <td>11</td>\n",
       "      <td>154</td>\n",
       "      <td>132</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9979</th>\n",
       "      <td>NaN</td>\n",
       "      <td>11</td>\n",
       "      <td>44</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>99</td>\n",
       "      <td>NaN</td>\n",
       "      <td>88</td>\n",
       "      <td>22</td>\n",
       "      <td>165</td>\n",
       "      <td>143</td>\n",
       "      <td>...</td>\n",
       "      <td>11</td>\n",
       "      <td>NaN</td>\n",
       "      <td>11</td>\n",
       "      <td>44</td>\n",
       "      <td>99</td>\n",
       "      <td>NaN</td>\n",
       "      <td>88</td>\n",
       "      <td>22</td>\n",
       "      <td>165</td>\n",
       "      <td>143</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9980</th>\n",
       "      <td>11</td>\n",
       "      <td>22</td>\n",
       "      <td>55</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>110</td>\n",
       "      <td>NaN</td>\n",
       "      <td>99</td>\n",
       "      <td>33</td>\n",
       "      <td>NaN</td>\n",
       "      <td>154</td>\n",
       "      <td>...</td>\n",
       "      <td>22</td>\n",
       "      <td>11</td>\n",
       "      <td>22</td>\n",
       "      <td>55</td>\n",
       "      <td>110</td>\n",
       "      <td>NaN</td>\n",
       "      <td>99</td>\n",
       "      <td>33</td>\n",
       "      <td>NaN</td>\n",
       "      <td>154</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9981</th>\n",
       "      <td>22</td>\n",
       "      <td>33</td>\n",
       "      <td>66</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>121</td>\n",
       "      <td>11</td>\n",
       "      <td>110</td>\n",
       "      <td>44</td>\n",
       "      <td>NaN</td>\n",
       "      <td>165</td>\n",
       "      <td>...</td>\n",
       "      <td>33</td>\n",
       "      <td>22</td>\n",
       "      <td>33</td>\n",
       "      <td>66</td>\n",
       "      <td>121</td>\n",
       "      <td>11</td>\n",
       "      <td>110</td>\n",
       "      <td>44</td>\n",
       "      <td>NaN</td>\n",
       "      <td>165</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9982</th>\n",
       "      <td>33</td>\n",
       "      <td>44</td>\n",
       "      <td>77</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>132</td>\n",
       "      <td>22</td>\n",
       "      <td>121</td>\n",
       "      <td>55</td>\n",
       "      <td>11</td>\n",
       "      <td>NaN</td>\n",
       "      <td>...</td>\n",
       "      <td>44</td>\n",
       "      <td>33</td>\n",
       "      <td>44</td>\n",
       "      <td>77</td>\n",
       "      <td>132</td>\n",
       "      <td>22</td>\n",
       "      <td>121</td>\n",
       "      <td>55</td>\n",
       "      <td>11</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9983</th>\n",
       "      <td>44</td>\n",
       "      <td>55</td>\n",
       "      <td>88</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>143</td>\n",
       "      <td>33</td>\n",
       "      <td>132</td>\n",
       "      <td>66</td>\n",
       "      <td>22</td>\n",
       "      <td>NaN</td>\n",
       "      <td>...</td>\n",
       "      <td>55</td>\n",
       "      <td>44</td>\n",
       "      <td>55</td>\n",
       "      <td>88</td>\n",
       "      <td>143</td>\n",
       "      <td>33</td>\n",
       "      <td>132</td>\n",
       "      <td>66</td>\n",
       "      <td>22</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9984</th>\n",
       "      <td>55</td>\n",
       "      <td>66</td>\n",
       "      <td>99</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>154</td>\n",
       "      <td>44</td>\n",
       "      <td>143</td>\n",
       "      <td>77</td>\n",
       "      <td>33</td>\n",
       "      <td>11</td>\n",
       "      <td>...</td>\n",
       "      <td>66</td>\n",
       "      <td>55</td>\n",
       "      <td>66</td>\n",
       "      <td>99</td>\n",
       "      <td>154</td>\n",
       "      <td>44</td>\n",
       "      <td>143</td>\n",
       "      <td>77</td>\n",
       "      <td>33</td>\n",
       "      <td>11</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9985</th>\n",
       "      <td>66</td>\n",
       "      <td>77</td>\n",
       "      <td>110</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>165</td>\n",
       "      <td>55</td>\n",
       "      <td>154</td>\n",
       "      <td>88</td>\n",
       "      <td>44</td>\n",
       "      <td>22</td>\n",
       "      <td>...</td>\n",
       "      <td>77</td>\n",
       "      <td>66</td>\n",
       "      <td>77</td>\n",
       "      <td>110</td>\n",
       "      <td>165</td>\n",
       "      <td>55</td>\n",
       "      <td>154</td>\n",
       "      <td>88</td>\n",
       "      <td>44</td>\n",
       "      <td>22</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9986</th>\n",
       "      <td>77</td>\n",
       "      <td>88</td>\n",
       "      <td>121</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>NaN</td>\n",
       "      <td>66</td>\n",
       "      <td>165</td>\n",
       "      <td>99</td>\n",
       "      <td>55</td>\n",
       "      <td>33</td>\n",
       "      <td>...</td>\n",
       "      <td>88</td>\n",
       "      <td>77</td>\n",
       "      <td>88</td>\n",
       "      <td>121</td>\n",
       "      <td>NaN</td>\n",
       "      <td>66</td>\n",
       "      <td>165</td>\n",
       "      <td>99</td>\n",
       "      <td>55</td>\n",
       "      <td>33</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9987</th>\n",
       "      <td>88</td>\n",
       "      <td>99</td>\n",
       "      <td>132</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>NaN</td>\n",
       "      <td>77</td>\n",
       "      <td>NaN</td>\n",
       "      <td>110</td>\n",
       "      <td>66</td>\n",
       "      <td>44</td>\n",
       "      <td>...</td>\n",
       "      <td>99</td>\n",
       "      <td>88</td>\n",
       "      <td>99</td>\n",
       "      <td>132</td>\n",
       "      <td>NaN</td>\n",
       "      <td>77</td>\n",
       "      <td>NaN</td>\n",
       "      <td>110</td>\n",
       "      <td>66</td>\n",
       "      <td>44</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9988</th>\n",
       "      <td>99</td>\n",
       "      <td>110</td>\n",
       "      <td>143</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>11</td>\n",
       "      <td>88</td>\n",
       "      <td>NaN</td>\n",
       "      <td>121</td>\n",
       "      <td>77</td>\n",
       "      <td>55</td>\n",
       "      <td>...</td>\n",
       "      <td>110</td>\n",
       "      <td>99</td>\n",
       "      <td>110</td>\n",
       "      <td>143</td>\n",
       "      <td>11</td>\n",
       "      <td>88</td>\n",
       "      <td>NaN</td>\n",
       "      <td>121</td>\n",
       "      <td>77</td>\n",
       "      <td>55</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9989</th>\n",
       "      <td>110</td>\n",
       "      <td>121</td>\n",
       "      <td>154</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>22</td>\n",
       "      <td>99</td>\n",
       "      <td>11</td>\n",
       "      <td>132</td>\n",
       "      <td>88</td>\n",
       "      <td>66</td>\n",
       "      <td>...</td>\n",
       "      <td>121</td>\n",
       "      <td>110</td>\n",
       "      <td>121</td>\n",
       "      <td>154</td>\n",
       "      <td>22</td>\n",
       "      <td>99</td>\n",
       "      <td>11</td>\n",
       "      <td>132</td>\n",
       "      <td>88</td>\n",
       "      <td>66</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9990</th>\n",
       "      <td>121</td>\n",
       "      <td>132</td>\n",
       "      <td>165</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>33</td>\n",
       "      <td>110</td>\n",
       "      <td>22</td>\n",
       "      <td>143</td>\n",
       "      <td>99</td>\n",
       "      <td>77</td>\n",
       "      <td>...</td>\n",
       "      <td>132</td>\n",
       "      <td>121</td>\n",
       "      <td>132</td>\n",
       "      <td>165</td>\n",
       "      <td>33</td>\n",
       "      <td>110</td>\n",
       "      <td>22</td>\n",
       "      <td>143</td>\n",
       "      <td>99</td>\n",
       "      <td>77</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9991</th>\n",
       "      <td>132</td>\n",
       "      <td>143</td>\n",
       "      <td>NaN</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>44</td>\n",
       "      <td>121</td>\n",
       "      <td>33</td>\n",
       "      <td>154</td>\n",
       "      <td>110</td>\n",
       "      <td>88</td>\n",
       "      <td>...</td>\n",
       "      <td>143</td>\n",
       "      <td>132</td>\n",
       "      <td>143</td>\n",
       "      <td>NaN</td>\n",
       "      <td>44</td>\n",
       "      <td>121</td>\n",
       "      <td>33</td>\n",
       "      <td>154</td>\n",
       "      <td>110</td>\n",
       "      <td>88</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9992</th>\n",
       "      <td>143</td>\n",
       "      <td>154</td>\n",
       "      <td>NaN</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>55</td>\n",
       "      <td>132</td>\n",
       "      <td>44</td>\n",
       "      <td>165</td>\n",
       "      <td>121</td>\n",
       "      <td>99</td>\n",
       "      <td>...</td>\n",
       "      <td>154</td>\n",
       "      <td>143</td>\n",
       "      <td>154</td>\n",
       "      <td>NaN</td>\n",
       "      <td>55</td>\n",
       "      <td>132</td>\n",
       "      <td>44</td>\n",
       "      <td>165</td>\n",
       "      <td>121</td>\n",
       "      <td>99</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9993</th>\n",
       "      <td>154</td>\n",
       "      <td>165</td>\n",
       "      <td>11</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>66</td>\n",
       "      <td>143</td>\n",
       "      <td>55</td>\n",
       "      <td>NaN</td>\n",
       "      <td>132</td>\n",
       "      <td>110</td>\n",
       "      <td>...</td>\n",
       "      <td>165</td>\n",
       "      <td>154</td>\n",
       "      <td>165</td>\n",
       "      <td>11</td>\n",
       "      <td>66</td>\n",
       "      <td>143</td>\n",
       "      <td>55</td>\n",
       "      <td>NaN</td>\n",
       "      <td>132</td>\n",
       "      <td>110</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9994</th>\n",
       "      <td>165</td>\n",
       "      <td>NaN</td>\n",
       "      <td>22</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>77</td>\n",
       "      <td>154</td>\n",
       "      <td>66</td>\n",
       "      <td>NaN</td>\n",
       "      <td>143</td>\n",
       "      <td>121</td>\n",
       "      <td>...</td>\n",
       "      <td>NaN</td>\n",
       "      <td>165</td>\n",
       "      <td>NaN</td>\n",
       "      <td>22</td>\n",
       "      <td>77</td>\n",
       "      <td>154</td>\n",
       "      <td>66</td>\n",
       "      <td>NaN</td>\n",
       "      <td>143</td>\n",
       "      <td>121</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9995</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>33</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>88</td>\n",
       "      <td>165</td>\n",
       "      <td>77</td>\n",
       "      <td>11</td>\n",
       "      <td>154</td>\n",
       "      <td>132</td>\n",
       "      <td>...</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>33</td>\n",
       "      <td>88</td>\n",
       "      <td>165</td>\n",
       "      <td>77</td>\n",
       "      <td>11</td>\n",
       "      <td>154</td>\n",
       "      <td>132</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9996</th>\n",
       "      <td>NaN</td>\n",
       "      <td>11</td>\n",
       "      <td>44</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>99</td>\n",
       "      <td>NaN</td>\n",
       "      <td>88</td>\n",
       "      <td>22</td>\n",
       "      <td>165</td>\n",
       "      <td>143</td>\n",
       "      <td>...</td>\n",
       "      <td>11</td>\n",
       "      <td>NaN</td>\n",
       "      <td>11</td>\n",
       "      <td>44</td>\n",
       "      <td>99</td>\n",
       "      <td>NaN</td>\n",
       "      <td>88</td>\n",
       "      <td>22</td>\n",
       "      <td>165</td>\n",
       "      <td>143</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9997</th>\n",
       "      <td>11</td>\n",
       "      <td>22</td>\n",
       "      <td>55</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>110</td>\n",
       "      <td>NaN</td>\n",
       "      <td>99</td>\n",
       "      <td>33</td>\n",
       "      <td>NaN</td>\n",
       "      <td>154</td>\n",
       "      <td>...</td>\n",
       "      <td>22</td>\n",
       "      <td>11</td>\n",
       "      <td>22</td>\n",
       "      <td>55</td>\n",
       "      <td>110</td>\n",
       "      <td>NaN</td>\n",
       "      <td>99</td>\n",
       "      <td>33</td>\n",
       "      <td>NaN</td>\n",
       "      <td>154</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9998</th>\n",
       "      <td>22</td>\n",
       "      <td>33</td>\n",
       "      <td>66</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>121</td>\n",
       "      <td>11</td>\n",
       "      <td>110</td>\n",
       "      <td>44</td>\n",
       "      <td>NaN</td>\n",
       "      <td>165</td>\n",
       "      <td>...</td>\n",
       "      <td>33</td>\n",
       "      <td>22</td>\n",
       "      <td>33</td>\n",
       "      <td>66</td>\n",
       "      <td>121</td>\n",
       "      <td>11</td>\n",
       "      <td>110</td>\n",
       "      <td>44</td>\n",
       "      <td>NaN</td>\n",
       "      <td>165</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9999</th>\n",
       "      <td>33</td>\n",
       "      <td>44</td>\n",
       "      <td>77</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>132</td>\n",
       "      <td>22</td>\n",
       "      <td>121</td>\n",
       "      <td>55</td>\n",
       "      <td>11</td>\n",
       "      <td>NaN</td>\n",
       "      <td>...</td>\n",
       "      <td>44</td>\n",
       "      <td>33</td>\n",
       "      <td>44</td>\n",
       "      <td>77</td>\n",
       "      <td>132</td>\n",
       "      <td>22</td>\n",
       "      <td>121</td>\n",
       "      <td>55</td>\n",
       "      <td>11</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>10000 rows × 27 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "        A    B    C some_text    D    E    F    G    H    I ...     Q    R  \\\n",
       "0     NaN   11   44    Blabla   99  NaN   88   22  165  143 ...    11  NaN   \n",
       "1      11   22   55    Blabla  110  NaN   99   33  NaN  154 ...    22   11   \n",
       "2      22   33   66    Blabla  121   11  110   44  NaN  165 ...    33   22   \n",
       "3      33   44   77    Blabla  132   22  121   55   11  NaN ...    44   33   \n",
       "4      44   55   88    Blabla  143   33  132   66   22  NaN ...    55   44   \n",
       "5      55   66   99    Blabla  154   44  143   77   33   11 ...    66   55   \n",
       "6      66   77  110    Blabla  165   55  154   88   44   22 ...    77   66   \n",
       "7      77   88  121    Blabla  NaN   66  165   99   55   33 ...    88   77   \n",
       "8      88   99  132    Blabla  NaN   77  NaN  110   66   44 ...    99   88   \n",
       "9      99  110  143    Blabla   11   88  NaN  121   77   55 ...   110   99   \n",
       "10    110  121  154    Blabla   22   99   11  132   88   66 ...   121  110   \n",
       "11    121  132  165    Blabla   33  110   22  143   99   77 ...   132  121   \n",
       "12    132  143  NaN    Blabla   44  121   33  154  110   88 ...   143  132   \n",
       "13    143  154  NaN    Blabla   55  132   44  165  121   99 ...   154  143   \n",
       "14    154  165   11    Blabla   66  143   55  NaN  132  110 ...   165  154   \n",
       "15    165  NaN   22    Blabla   77  154   66  NaN  143  121 ...   NaN  165   \n",
       "16    NaN  NaN   33    Blabla   88  165   77   11  154  132 ...   NaN  NaN   \n",
       "17    NaN   11   44    Blabla   99  NaN   88   22  165  143 ...    11  NaN   \n",
       "18     11   22   55    Blabla  110  NaN   99   33  NaN  154 ...    22   11   \n",
       "19     22   33   66    Blabla  121   11  110   44  NaN  165 ...    33   22   \n",
       "20     33   44   77    Blabla  132   22  121   55   11  NaN ...    44   33   \n",
       "21     44   55   88    Blabla  143   33  132   66   22  NaN ...    55   44   \n",
       "22     55   66   99    Blabla  154   44  143   77   33   11 ...    66   55   \n",
       "23     66   77  110    Blabla  165   55  154   88   44   22 ...    77   66   \n",
       "24     77   88  121    Blabla  NaN   66  165   99   55   33 ...    88   77   \n",
       "25     88   99  132    Blabla  NaN   77  NaN  110   66   44 ...    99   88   \n",
       "26     99  110  143    Blabla   11   88  NaN  121   77   55 ...   110   99   \n",
       "27    110  121  154    Blabla   22   99   11  132   88   66 ...   121  110   \n",
       "28    121  132  165    Blabla   33  110   22  143   99   77 ...   132  121   \n",
       "29    132  143  NaN    Blabla   44  121   33  154  110   88 ...   143  132   \n",
       "...   ...  ...  ...       ...  ...  ...  ...  ...  ...  ... ...   ...  ...   \n",
       "9970   88   99  132    Blabla  NaN   77  NaN  110   66   44 ...    99   88   \n",
       "9971   99  110  143    Blabla   11   88  NaN  121   77   55 ...   110   99   \n",
       "9972  110  121  154    Blabla   22   99   11  132   88   66 ...   121  110   \n",
       "9973  121  132  165    Blabla   33  110   22  143   99   77 ...   132  121   \n",
       "9974  132  143  NaN    Blabla   44  121   33  154  110   88 ...   143  132   \n",
       "9975  143  154  NaN    Blabla   55  132   44  165  121   99 ...   154  143   \n",
       "9976  154  165   11    Blabla   66  143   55  NaN  132  110 ...   165  154   \n",
       "9977  165  NaN   22    Blabla   77  154   66  NaN  143  121 ...   NaN  165   \n",
       "9978  NaN  NaN   33    Blabla   88  165   77   11  154  132 ...   NaN  NaN   \n",
       "9979  NaN   11   44    Blabla   99  NaN   88   22  165  143 ...    11  NaN   \n",
       "9980   11   22   55    Blabla  110  NaN   99   33  NaN  154 ...    22   11   \n",
       "9981   22   33   66    Blabla  121   11  110   44  NaN  165 ...    33   22   \n",
       "9982   33   44   77    Blabla  132   22  121   55   11  NaN ...    44   33   \n",
       "9983   44   55   88    Blabla  143   33  132   66   22  NaN ...    55   44   \n",
       "9984   55   66   99    Blabla  154   44  143   77   33   11 ...    66   55   \n",
       "9985   66   77  110    Blabla  165   55  154   88   44   22 ...    77   66   \n",
       "9986   77   88  121    Blabla  NaN   66  165   99   55   33 ...    88   77   \n",
       "9987   88   99  132    Blabla  NaN   77  NaN  110   66   44 ...    99   88   \n",
       "9988   99  110  143    Blabla   11   88  NaN  121   77   55 ...   110   99   \n",
       "9989  110  121  154    Blabla   22   99   11  132   88   66 ...   121  110   \n",
       "9990  121  132  165    Blabla   33  110   22  143   99   77 ...   132  121   \n",
       "9991  132  143  NaN    Blabla   44  121   33  154  110   88 ...   143  132   \n",
       "9992  143  154  NaN    Blabla   55  132   44  165  121   99 ...   154  143   \n",
       "9993  154  165   11    Blabla   66  143   55  NaN  132  110 ...   165  154   \n",
       "9994  165  NaN   22    Blabla   77  154   66  NaN  143  121 ...   NaN  165   \n",
       "9995  NaN  NaN   33    Blabla   88  165   77   11  154  132 ...   NaN  NaN   \n",
       "9996  NaN   11   44    Blabla   99  NaN   88   22  165  143 ...    11  NaN   \n",
       "9997   11   22   55    Blabla  110  NaN   99   33  NaN  154 ...    22   11   \n",
       "9998   22   33   66    Blabla  121   11  110   44  NaN  165 ...    33   22   \n",
       "9999   33   44   77    Blabla  132   22  121   55   11  NaN ...    44   33   \n",
       "\n",
       "        S    T    U    V    W    X    Y    Z  \n",
       "0      11   44   99  NaN   88   22  165  143  \n",
       "1      22   55  110  NaN   99   33  NaN  154  \n",
       "2      33   66  121   11  110   44  NaN  165  \n",
       "3      44   77  132   22  121   55   11  NaN  \n",
       "4      55   88  143   33  132   66   22  NaN  \n",
       "5      66   99  154   44  143   77   33   11  \n",
       "6      77  110  165   55  154   88   44   22  \n",
       "7      88  121  NaN   66  165   99   55   33  \n",
       "8      99  132  NaN   77  NaN  110   66   44  \n",
       "9     110  143   11   88  NaN  121   77   55  \n",
       "10    121  154   22   99   11  132   88   66  \n",
       "11    132  165   33  110   22  143   99   77  \n",
       "12    143  NaN   44  121   33  154  110   88  \n",
       "13    154  NaN   55  132   44  165  121   99  \n",
       "14    165   11   66  143   55  NaN  132  110  \n",
       "15    NaN   22   77  154   66  NaN  143  121  \n",
       "16    NaN   33   88  165   77   11  154  132  \n",
       "17     11   44   99  NaN   88   22  165  143  \n",
       "18     22   55  110  NaN   99   33  NaN  154  \n",
       "19     33   66  121   11  110   44  NaN  165  \n",
       "20     44   77  132   22  121   55   11  NaN  \n",
       "21     55   88  143   33  132   66   22  NaN  \n",
       "22     66   99  154   44  143   77   33   11  \n",
       "23     77  110  165   55  154   88   44   22  \n",
       "24     88  121  NaN   66  165   99   55   33  \n",
       "25     99  132  NaN   77  NaN  110   66   44  \n",
       "26    110  143   11   88  NaN  121   77   55  \n",
       "27    121  154   22   99   11  132   88   66  \n",
       "28    132  165   33  110   22  143   99   77  \n",
       "29    143  NaN   44  121   33  154  110   88  \n",
       "...   ...  ...  ...  ...  ...  ...  ...  ...  \n",
       "9970   99  132  NaN   77  NaN  110   66   44  \n",
       "9971  110  143   11   88  NaN  121   77   55  \n",
       "9972  121  154   22   99   11  132   88   66  \n",
       "9973  132  165   33  110   22  143   99   77  \n",
       "9974  143  NaN   44  121   33  154  110   88  \n",
       "9975  154  NaN   55  132   44  165  121   99  \n",
       "9976  165   11   66  143   55  NaN  132  110  \n",
       "9977  NaN   22   77  154   66  NaN  143  121  \n",
       "9978  NaN   33   88  165   77   11  154  132  \n",
       "9979   11   44   99  NaN   88   22  165  143  \n",
       "9980   22   55  110  NaN   99   33  NaN  154  \n",
       "9981   33   66  121   11  110   44  NaN  165  \n",
       "9982   44   77  132   22  121   55   11  NaN  \n",
       "9983   55   88  143   33  132   66   22  NaN  \n",
       "9984   66   99  154   44  143   77   33   11  \n",
       "9985   77  110  165   55  154   88   44   22  \n",
       "9986   88  121  NaN   66  165   99   55   33  \n",
       "9987   99  132  NaN   77  NaN  110   66   44  \n",
       "9988  110  143   11   88  NaN  121   77   55  \n",
       "9989  121  154   22   99   11  132   88   66  \n",
       "9990  132  165   33  110   22  143   99   77  \n",
       "9991  143  NaN   44  121   33  154  110   88  \n",
       "9992  154  NaN   55  132   44  165  121   99  \n",
       "9993  165   11   66  143   55  NaN  132  110  \n",
       "9994  NaN   22   77  154   66  NaN  143  121  \n",
       "9995  NaN   33   88  165   77   11  154  132  \n",
       "9996   11   44   99  NaN   88   22  165  143  \n",
       "9997   22   55  110  NaN   99   33  NaN  154  \n",
       "9998   33   66  121   11  110   44  NaN  165  \n",
       "9999   44   77  132   22  121   55   11  NaN  \n",
       "\n",
       "[10000 rows x 27 columns]"
      ]
     },
     "execution_count": 123,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "much_data = np.fromfunction(lambda x,y: (x+y*y)%17*11, (10000, 26))\n",
    "large_df = pd.DataFrame(much_data, columns=list(\"ABCDEFGHIJKLMNOPQRSTUVWXYZ\"))\n",
    "large_df[large_df % 16 == 0] = np.nan\n",
    "large_df.insert(3,\"some_text\", \"Blabla\")\n",
    "large_df"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The `head` method returns the top 5 rows:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 124,
   "metadata": {
    "collapsed": false,
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>A</th>\n",
       "      <th>B</th>\n",
       "      <th>C</th>\n",
       "      <th>some_text</th>\n",
       "      <th>D</th>\n",
       "      <th>E</th>\n",
       "      <th>F</th>\n",
       "      <th>G</th>\n",
       "      <th>H</th>\n",
       "      <th>I</th>\n",
       "      <th>...</th>\n",
       "      <th>Q</th>\n",
       "      <th>R</th>\n",
       "      <th>S</th>\n",
       "      <th>T</th>\n",
       "      <th>U</th>\n",
       "      <th>V</th>\n",
       "      <th>W</th>\n",
       "      <th>X</th>\n",
       "      <th>Y</th>\n",
       "      <th>Z</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>NaN</td>\n",
       "      <td>11</td>\n",
       "      <td>44</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>99</td>\n",
       "      <td>NaN</td>\n",
       "      <td>88</td>\n",
       "      <td>22</td>\n",
       "      <td>165</td>\n",
       "      <td>143</td>\n",
       "      <td>...</td>\n",
       "      <td>11</td>\n",
       "      <td>NaN</td>\n",
       "      <td>11</td>\n",
       "      <td>44</td>\n",
       "      <td>99</td>\n",
       "      <td>NaN</td>\n",
       "      <td>88</td>\n",
       "      <td>22</td>\n",
       "      <td>165</td>\n",
       "      <td>143</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>11</td>\n",
       "      <td>22</td>\n",
       "      <td>55</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>110</td>\n",
       "      <td>NaN</td>\n",
       "      <td>99</td>\n",
       "      <td>33</td>\n",
       "      <td>NaN</td>\n",
       "      <td>154</td>\n",
       "      <td>...</td>\n",
       "      <td>22</td>\n",
       "      <td>11</td>\n",
       "      <td>22</td>\n",
       "      <td>55</td>\n",
       "      <td>110</td>\n",
       "      <td>NaN</td>\n",
       "      <td>99</td>\n",
       "      <td>33</td>\n",
       "      <td>NaN</td>\n",
       "      <td>154</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>22</td>\n",
       "      <td>33</td>\n",
       "      <td>66</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>121</td>\n",
       "      <td>11</td>\n",
       "      <td>110</td>\n",
       "      <td>44</td>\n",
       "      <td>NaN</td>\n",
       "      <td>165</td>\n",
       "      <td>...</td>\n",
       "      <td>33</td>\n",
       "      <td>22</td>\n",
       "      <td>33</td>\n",
       "      <td>66</td>\n",
       "      <td>121</td>\n",
       "      <td>11</td>\n",
       "      <td>110</td>\n",
       "      <td>44</td>\n",
       "      <td>NaN</td>\n",
       "      <td>165</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>33</td>\n",
       "      <td>44</td>\n",
       "      <td>77</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>132</td>\n",
       "      <td>22</td>\n",
       "      <td>121</td>\n",
       "      <td>55</td>\n",
       "      <td>11</td>\n",
       "      <td>NaN</td>\n",
       "      <td>...</td>\n",
       "      <td>44</td>\n",
       "      <td>33</td>\n",
       "      <td>44</td>\n",
       "      <td>77</td>\n",
       "      <td>132</td>\n",
       "      <td>22</td>\n",
       "      <td>121</td>\n",
       "      <td>55</td>\n",
       "      <td>11</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>44</td>\n",
       "      <td>55</td>\n",
       "      <td>88</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>143</td>\n",
       "      <td>33</td>\n",
       "      <td>132</td>\n",
       "      <td>66</td>\n",
       "      <td>22</td>\n",
       "      <td>NaN</td>\n",
       "      <td>...</td>\n",
       "      <td>55</td>\n",
       "      <td>44</td>\n",
       "      <td>55</td>\n",
       "      <td>88</td>\n",
       "      <td>143</td>\n",
       "      <td>33</td>\n",
       "      <td>132</td>\n",
       "      <td>66</td>\n",
       "      <td>22</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>5 rows × 27 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "    A   B   C some_text    D   E    F   G    H    I ...    Q   R   S   T    U  \\\n",
       "0 NaN  11  44    Blabla   99 NaN   88  22  165  143 ...   11 NaN  11  44   99   \n",
       "1  11  22  55    Blabla  110 NaN   99  33  NaN  154 ...   22  11  22  55  110   \n",
       "2  22  33  66    Blabla  121  11  110  44  NaN  165 ...   33  22  33  66  121   \n",
       "3  33  44  77    Blabla  132  22  121  55   11  NaN ...   44  33  44  77  132   \n",
       "4  44  55  88    Blabla  143  33  132  66   22  NaN ...   55  44  55  88  143   \n",
       "\n",
       "    V    W   X    Y    Z  \n",
       "0 NaN   88  22  165  143  \n",
       "1 NaN   99  33  NaN  154  \n",
       "2  11  110  44  NaN  165  \n",
       "3  22  121  55   11  NaN  \n",
       "4  33  132  66   22  NaN  \n",
       "\n",
       "[5 rows x 27 columns]"
      ]
     },
     "execution_count": 124,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "large_df.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Of course there's also a `tail` function to view the bottom 5 rows. You can pass the number of rows you want:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 125,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>A</th>\n",
       "      <th>B</th>\n",
       "      <th>C</th>\n",
       "      <th>some_text</th>\n",
       "      <th>D</th>\n",
       "      <th>E</th>\n",
       "      <th>F</th>\n",
       "      <th>G</th>\n",
       "      <th>H</th>\n",
       "      <th>I</th>\n",
       "      <th>...</th>\n",
       "      <th>Q</th>\n",
       "      <th>R</th>\n",
       "      <th>S</th>\n",
       "      <th>T</th>\n",
       "      <th>U</th>\n",
       "      <th>V</th>\n",
       "      <th>W</th>\n",
       "      <th>X</th>\n",
       "      <th>Y</th>\n",
       "      <th>Z</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>9998</th>\n",
       "      <td>22</td>\n",
       "      <td>33</td>\n",
       "      <td>66</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>121</td>\n",
       "      <td>11</td>\n",
       "      <td>110</td>\n",
       "      <td>44</td>\n",
       "      <td>NaN</td>\n",
       "      <td>165</td>\n",
       "      <td>...</td>\n",
       "      <td>33</td>\n",
       "      <td>22</td>\n",
       "      <td>33</td>\n",
       "      <td>66</td>\n",
       "      <td>121</td>\n",
       "      <td>11</td>\n",
       "      <td>110</td>\n",
       "      <td>44</td>\n",
       "      <td>NaN</td>\n",
       "      <td>165</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9999</th>\n",
       "      <td>33</td>\n",
       "      <td>44</td>\n",
       "      <td>77</td>\n",
       "      <td>Blabla</td>\n",
       "      <td>132</td>\n",
       "      <td>22</td>\n",
       "      <td>121</td>\n",
       "      <td>55</td>\n",
       "      <td>11</td>\n",
       "      <td>NaN</td>\n",
       "      <td>...</td>\n",
       "      <td>44</td>\n",
       "      <td>33</td>\n",
       "      <td>44</td>\n",
       "      <td>77</td>\n",
       "      <td>132</td>\n",
       "      <td>22</td>\n",
       "      <td>121</td>\n",
       "      <td>55</td>\n",
       "      <td>11</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>2 rows × 27 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "       A   B   C some_text    D   E    F   G   H    I ...    Q   R   S   T  \\\n",
       "9998  22  33  66    Blabla  121  11  110  44 NaN  165 ...   33  22  33  66   \n",
       "9999  33  44  77    Blabla  132  22  121  55  11  NaN ...   44  33  44  77   \n",
       "\n",
       "        U   V    W   X   Y    Z  \n",
       "9998  121  11  110  44 NaN  165  \n",
       "9999  132  22  121  55  11  NaN  \n",
       "\n",
       "[2 rows x 27 columns]"
      ]
     },
     "execution_count": 125,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "large_df.tail(n=2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The `info` method prints out a summary of each columns contents:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 126,
   "metadata": {
    "collapsed": false,
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "Int64Index: 10000 entries, 0 to 9999\n",
      "Data columns (total 27 columns):\n",
      "A            8823 non-null float64\n",
      "B            8824 non-null float64\n",
      "C            8824 non-null float64\n",
      "some_text    10000 non-null object\n",
      "D            8824 non-null float64\n",
      "E            8822 non-null float64\n",
      "F            8824 non-null float64\n",
      "G            8824 non-null float64\n",
      "H            8822 non-null float64\n",
      "I            8823 non-null float64\n",
      "J            8823 non-null float64\n",
      "K            8822 non-null float64\n",
      "L            8824 non-null float64\n",
      "M            8824 non-null float64\n",
      "N            8822 non-null float64\n",
      "O            8824 non-null float64\n",
      "P            8824 non-null float64\n",
      "Q            8824 non-null float64\n",
      "R            8823 non-null float64\n",
      "S            8824 non-null float64\n",
      "T            8824 non-null float64\n",
      "U            8824 non-null float64\n",
      "V            8822 non-null float64\n",
      "W            8824 non-null float64\n",
      "X            8824 non-null float64\n",
      "Y            8822 non-null float64\n",
      "Z            8823 non-null float64\n",
      "dtypes: float64(26), object(1)\n",
      "memory usage: 2.1+ MB\n"
     ]
    }
   ],
   "source": [
    "large_df.info()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Finally, the `describe` method gives a nice overview of the main aggregated values over each column:\n",
    "* `count`: number of non-null (not NaN) values\n",
    "* `mean`: mean of non-null values\n",
    "* `std`: [standard deviation](https://en.wikipedia.org/wiki/Standard_deviation) of non-null values\n",
    "* `min`: minimum of non-null values\n",
    "* `25%`, `50%`, `75%`: 25th, 50th and 75th [percentile](https://en.wikipedia.org/wiki/Percentile) of non-null values\n",
    "* `max`: maximum of non-null values"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 127,
   "metadata": {
    "collapsed": false,
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>A</th>\n",
       "      <th>B</th>\n",
       "      <th>C</th>\n",
       "      <th>D</th>\n",
       "      <th>E</th>\n",
       "      <th>F</th>\n",
       "      <th>G</th>\n",
       "      <th>H</th>\n",
       "      <th>I</th>\n",
       "      <th>J</th>\n",
       "      <th>...</th>\n",
       "      <th>Q</th>\n",
       "      <th>R</th>\n",
       "      <th>S</th>\n",
       "      <th>T</th>\n",
       "      <th>U</th>\n",
       "      <th>V</th>\n",
       "      <th>W</th>\n",
       "      <th>X</th>\n",
       "      <th>Y</th>\n",
       "      <th>Z</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>count</th>\n",
       "      <td>8823.000000</td>\n",
       "      <td>8824.000000</td>\n",
       "      <td>8824.000000</td>\n",
       "      <td>8824.000000</td>\n",
       "      <td>8822.000000</td>\n",
       "      <td>8824.000000</td>\n",
       "      <td>8824.000000</td>\n",
       "      <td>8822.000000</td>\n",
       "      <td>8823.000000</td>\n",
       "      <td>8823.000000</td>\n",
       "      <td>...</td>\n",
       "      <td>8824.000000</td>\n",
       "      <td>8823.000000</td>\n",
       "      <td>8824.000000</td>\n",
       "      <td>8824.000000</td>\n",
       "      <td>8824.000000</td>\n",
       "      <td>8822.000000</td>\n",
       "      <td>8824.000000</td>\n",
       "      <td>8824.000000</td>\n",
       "      <td>8822.000000</td>\n",
       "      <td>8823.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>mean</th>\n",
       "      <td>87.977559</td>\n",
       "      <td>87.972575</td>\n",
       "      <td>87.987534</td>\n",
       "      <td>88.012466</td>\n",
       "      <td>87.983791</td>\n",
       "      <td>88.007480</td>\n",
       "      <td>87.977561</td>\n",
       "      <td>88.000000</td>\n",
       "      <td>88.022441</td>\n",
       "      <td>88.022441</td>\n",
       "      <td>...</td>\n",
       "      <td>87.972575</td>\n",
       "      <td>87.977559</td>\n",
       "      <td>87.972575</td>\n",
       "      <td>87.987534</td>\n",
       "      <td>88.012466</td>\n",
       "      <td>87.983791</td>\n",
       "      <td>88.007480</td>\n",
       "      <td>87.977561</td>\n",
       "      <td>88.000000</td>\n",
       "      <td>88.022441</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>std</th>\n",
       "      <td>47.535911</td>\n",
       "      <td>47.535523</td>\n",
       "      <td>47.521679</td>\n",
       "      <td>47.521679</td>\n",
       "      <td>47.535001</td>\n",
       "      <td>47.519371</td>\n",
       "      <td>47.529755</td>\n",
       "      <td>47.536879</td>\n",
       "      <td>47.535911</td>\n",
       "      <td>47.535911</td>\n",
       "      <td>...</td>\n",
       "      <td>47.535523</td>\n",
       "      <td>47.535911</td>\n",
       "      <td>47.535523</td>\n",
       "      <td>47.521679</td>\n",
       "      <td>47.521679</td>\n",
       "      <td>47.535001</td>\n",
       "      <td>47.519371</td>\n",
       "      <td>47.529755</td>\n",
       "      <td>47.536879</td>\n",
       "      <td>47.535911</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>min</th>\n",
       "      <td>11.000000</td>\n",
       "      <td>11.000000</td>\n",
       "      <td>11.000000</td>\n",
       "      <td>11.000000</td>\n",
       "      <td>11.000000</td>\n",
       "      <td>11.000000</td>\n",
       "      <td>11.000000</td>\n",
       "      <td>11.000000</td>\n",
       "      <td>11.000000</td>\n",
       "      <td>11.000000</td>\n",
       "      <td>...</td>\n",
       "      <td>11.000000</td>\n",
       "      <td>11.000000</td>\n",
       "      <td>11.000000</td>\n",
       "      <td>11.000000</td>\n",
       "      <td>11.000000</td>\n",
       "      <td>11.000000</td>\n",
       "      <td>11.000000</td>\n",
       "      <td>11.000000</td>\n",
       "      <td>11.000000</td>\n",
       "      <td>11.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>25%</th>\n",
       "      <td>44.000000</td>\n",
       "      <td>44.000000</td>\n",
       "      <td>44.000000</td>\n",
       "      <td>44.000000</td>\n",
       "      <td>44.000000</td>\n",
       "      <td>44.000000</td>\n",
       "      <td>44.000000</td>\n",
       "      <td>44.000000</td>\n",
       "      <td>44.000000</td>\n",
       "      <td>44.000000</td>\n",
       "      <td>...</td>\n",
       "      <td>44.000000</td>\n",
       "      <td>44.000000</td>\n",
       "      <td>44.000000</td>\n",
       "      <td>44.000000</td>\n",
       "      <td>44.000000</td>\n",
       "      <td>44.000000</td>\n",
       "      <td>44.000000</td>\n",
       "      <td>44.000000</td>\n",
       "      <td>44.000000</td>\n",
       "      <td>44.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>50%</th>\n",
       "      <td>88.000000</td>\n",
       "      <td>88.000000</td>\n",
       "      <td>88.000000</td>\n",
       "      <td>88.000000</td>\n",
       "      <td>88.000000</td>\n",
       "      <td>88.000000</td>\n",
       "      <td>88.000000</td>\n",
       "      <td>88.000000</td>\n",
       "      <td>88.000000</td>\n",
       "      <td>88.000000</td>\n",
       "      <td>...</td>\n",
       "      <td>88.000000</td>\n",
       "      <td>88.000000</td>\n",
       "      <td>88.000000</td>\n",
       "      <td>88.000000</td>\n",
       "      <td>88.000000</td>\n",
       "      <td>88.000000</td>\n",
       "      <td>88.000000</td>\n",
       "      <td>88.000000</td>\n",
       "      <td>88.000000</td>\n",
       "      <td>88.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>75%</th>\n",
       "      <td>132.000000</td>\n",
       "      <td>132.000000</td>\n",
       "      <td>132.000000</td>\n",
       "      <td>132.000000</td>\n",
       "      <td>132.000000</td>\n",
       "      <td>132.000000</td>\n",
       "      <td>132.000000</td>\n",
       "      <td>132.000000</td>\n",
       "      <td>132.000000</td>\n",
       "      <td>132.000000</td>\n",
       "      <td>...</td>\n",
       "      <td>132.000000</td>\n",
       "      <td>132.000000</td>\n",
       "      <td>132.000000</td>\n",
       "      <td>132.000000</td>\n",
       "      <td>132.000000</td>\n",
       "      <td>132.000000</td>\n",
       "      <td>132.000000</td>\n",
       "      <td>132.000000</td>\n",
       "      <td>132.000000</td>\n",
       "      <td>132.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>max</th>\n",
       "      <td>165.000000</td>\n",
       "      <td>165.000000</td>\n",
       "      <td>165.000000</td>\n",
       "      <td>165.000000</td>\n",
       "      <td>165.000000</td>\n",
       "      <td>165.000000</td>\n",
       "      <td>165.000000</td>\n",
       "      <td>165.000000</td>\n",
       "      <td>165.000000</td>\n",
       "      <td>165.000000</td>\n",
       "      <td>...</td>\n",
       "      <td>165.000000</td>\n",
       "      <td>165.000000</td>\n",
       "      <td>165.000000</td>\n",
       "      <td>165.000000</td>\n",
       "      <td>165.000000</td>\n",
       "      <td>165.000000</td>\n",
       "      <td>165.000000</td>\n",
       "      <td>165.000000</td>\n",
       "      <td>165.000000</td>\n",
       "      <td>165.000000</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>8 rows × 26 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "                 A            B            C            D            E  \\\n",
       "count  8823.000000  8824.000000  8824.000000  8824.000000  8822.000000   \n",
       "mean     87.977559    87.972575    87.987534    88.012466    87.983791   \n",
       "std      47.535911    47.535523    47.521679    47.521679    47.535001   \n",
       "min      11.000000    11.000000    11.000000    11.000000    11.000000   \n",
       "25%      44.000000    44.000000    44.000000    44.000000    44.000000   \n",
       "50%      88.000000    88.000000    88.000000    88.000000    88.000000   \n",
       "75%     132.000000   132.000000   132.000000   132.000000   132.000000   \n",
       "max     165.000000   165.000000   165.000000   165.000000   165.000000   \n",
       "\n",
       "                 F            G            H            I            J  \\\n",
       "count  8824.000000  8824.000000  8822.000000  8823.000000  8823.000000   \n",
       "mean     88.007480    87.977561    88.000000    88.022441    88.022441   \n",
       "std      47.519371    47.529755    47.536879    47.535911    47.535911   \n",
       "min      11.000000    11.000000    11.000000    11.000000    11.000000   \n",
       "25%      44.000000    44.000000    44.000000    44.000000    44.000000   \n",
       "50%      88.000000    88.000000    88.000000    88.000000    88.000000   \n",
       "75%     132.000000   132.000000   132.000000   132.000000   132.000000   \n",
       "max     165.000000   165.000000   165.000000   165.000000   165.000000   \n",
       "\n",
       "          ...                 Q            R            S            T  \\\n",
       "count     ...       8824.000000  8823.000000  8824.000000  8824.000000   \n",
       "mean      ...         87.972575    87.977559    87.972575    87.987534   \n",
       "std       ...         47.535523    47.535911    47.535523    47.521679   \n",
       "min       ...         11.000000    11.000000    11.000000    11.000000   \n",
       "25%       ...         44.000000    44.000000    44.000000    44.000000   \n",
       "50%       ...         88.000000    88.000000    88.000000    88.000000   \n",
       "75%       ...        132.000000   132.000000   132.000000   132.000000   \n",
       "max       ...        165.000000   165.000000   165.000000   165.000000   \n",
       "\n",
       "                 U            V            W            X            Y  \\\n",
       "count  8824.000000  8822.000000  8824.000000  8824.000000  8822.000000   \n",
       "mean     88.012466    87.983791    88.007480    87.977561    88.000000   \n",
       "std      47.521679    47.535001    47.519371    47.529755    47.536879   \n",
       "min      11.000000    11.000000    11.000000    11.000000    11.000000   \n",
       "25%      44.000000    44.000000    44.000000    44.000000    44.000000   \n",
       "50%      88.000000    88.000000    88.000000    88.000000    88.000000   \n",
       "75%     132.000000   132.000000   132.000000   132.000000   132.000000   \n",
       "max     165.000000   165.000000   165.000000   165.000000   165.000000   \n",
       "\n",
       "                 Z  \n",
       "count  8823.000000  \n",
       "mean     88.022441  \n",
       "std      47.535911  \n",
       "min      11.000000  \n",
       "25%      44.000000  \n",
       "50%      88.000000  \n",
       "75%     132.000000  \n",
       "max     165.000000  \n",
       "\n",
       "[8 rows x 26 columns]"
      ]
     },
     "execution_count": 127,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "large_df.describe()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Saving & loading\n",
    "Pandas can save `DataFrame`s to various backends, including file formats such as CSV, Excel, JSON, HTML and HDF5, or to a SQL database. Let's create a `DataFrame` to demonstrate this:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 128,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>hobby</th>\n",
       "      <th>weight</th>\n",
       "      <th>birthyear</th>\n",
       "      <th>children</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>alice</th>\n",
       "      <td>Biking</td>\n",
       "      <td>68.5</td>\n",
       "      <td>1985</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>bob</th>\n",
       "      <td>Dancing</td>\n",
       "      <td>83.1</td>\n",
       "      <td>1984</td>\n",
       "      <td>3</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "         hobby  weight  birthyear  children\n",
       "alice   Biking    68.5       1985       NaN\n",
       "bob    Dancing    83.1       1984         3"
      ]
     },
     "execution_count": 128,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "my_df = pd.DataFrame(\n",
    "    [[\"Biking\", 68.5, 1985, np.nan], [\"Dancing\", 83.1, 1984, 3]], \n",
    "    columns=[\"hobby\",\"weight\",\"birthyear\",\"children\"],\n",
    "    index=[\"alice\", \"bob\"]\n",
    ")\n",
    "my_df"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Saving\n",
    "Let's save it to CSV, HTML and JSON:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 129,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "my_df.to_csv(\"my_df.csv\")\n",
    "my_df.to_html(\"my_df.html\")\n",
    "my_df.to_json(\"my_df.json\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Done! Let's take a peek at what was saved:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 130,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "# my_df.csv\n",
      ",hobby,weight,birthyear,children\n",
      "alice,Biking,68.5,1985,\n",
      "bob,Dancing,83.1,1984,3.0\n",
      "\n",
      "\n",
      "# my_df.html\n",
      "<table border=\"1\" class=\"dataframe\">\n",
      "  <thead>\n",
      "    <tr style=\"text-align: right;\">\n",
      "      <th></th>\n",
      "      <th>hobby</th>\n",
      "      <th>weight</th>\n",
      "      <th>birthyear</th>\n",
      "      <th>children</th>\n",
      "    </tr>\n",
      "  </thead>\n",
      "  <tbody>\n",
      "    <tr>\n",
      "      <th>alice</th>\n",
      "      <td>Biking</td>\n",
      "      <td>68.5</td>\n",
      "      <td>1985</td>\n",
      "      <td>NaN</td>\n",
      "    </tr>\n",
      "    <tr>\n",
      "      <th>bob</th>\n",
      "      <td>Dancing</td>\n",
      "      <td>83.1</td>\n",
      "      <td>1984</td>\n",
      "      <td>3</td>\n",
      "    </tr>\n",
      "  </tbody>\n",
      "</table>\n",
      "\n",
      "# my_df.json\n",
      "{\"hobby\":{\"alice\":\"Biking\",\"bob\":\"Dancing\"},\"weight\":{\"alice\":68.5,\"bob\":83.1},\"birthyear\":{\"alice\":1985,\"bob\":1984},\"children\":{\"alice\":null,\"bob\":3.0}}\n",
      "\n"
     ]
    }
   ],
   "source": [
    "for filename in (\"my_df.csv\", \"my_df.html\", \"my_df.json\"):\n",
    "    print(\"#\", filename)\n",
    "    with open(filename, \"rt\") as f:\n",
    "        print(f.read())\n",
    "        print()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Note that the index is saved as the first column (with no name) in a CSV file, as `<th>` tags in HTML and as keys in JSON.\n",
    "\n",
    "Saving to other formats works very similarly, but some formats require extra libraries to be installed. For example, saving to Excel requires the openpyxl library:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 131,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "No module named openpyxl\n"
     ]
    }
   ],
   "source": [
    "try:\n",
    "    my_df.to_excel(\"my_df.xlsx\", sheet_name='People')\n",
    "except ImportError as e:\n",
    "    print(e)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Loading\n",
    "Now let's load our CSV file back into a `DataFrame`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 132,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>hobby</th>\n",
       "      <th>weight</th>\n",
       "      <th>birthyear</th>\n",
       "      <th>children</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>alice</th>\n",
       "      <td>Biking</td>\n",
       "      <td>68.5</td>\n",
       "      <td>1985</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>bob</th>\n",
       "      <td>Dancing</td>\n",
       "      <td>83.1</td>\n",
       "      <td>1984</td>\n",
       "      <td>3</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "         hobby  weight  birthyear  children\n",
       "alice   Biking    68.5       1985       NaN\n",
       "bob    Dancing    83.1       1984         3"
      ]
     },
     "execution_count": 132,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "my_df_loaded = pd.read_csv(\"my_df.csv\", index_col=0)\n",
    "my_df_loaded"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As you might guess, there are similar `read_json`, `read_html`, `read_excel` functions as well.  We can also read data straight from the Internet. For example, let's load all U.S. cities from [simplemaps.com](http://simplemaps.com/):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 133,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>state</th>\n",
       "      <th>city</th>\n",
       "      <th>lat</th>\n",
       "      <th>lng</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>zip</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>35004</th>\n",
       "      <td>AL</td>\n",
       "      <td>Acmar</td>\n",
       "      <td>33.584132</td>\n",
       "      <td>-86.515570</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>35005</th>\n",
       "      <td>AL</td>\n",
       "      <td>Adamsville</td>\n",
       "      <td>33.588437</td>\n",
       "      <td>-86.959727</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>35006</th>\n",
       "      <td>AL</td>\n",
       "      <td>Adger</td>\n",
       "      <td>33.434277</td>\n",
       "      <td>-87.167455</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>35007</th>\n",
       "      <td>AL</td>\n",
       "      <td>Keystone</td>\n",
       "      <td>33.236868</td>\n",
       "      <td>-86.812861</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>35010</th>\n",
       "      <td>AL</td>\n",
       "      <td>New Site</td>\n",
       "      <td>32.941445</td>\n",
       "      <td>-85.951086</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "      state        city        lat        lng\n",
       "zip                                          \n",
       "35004    AL       Acmar  33.584132 -86.515570\n",
       "35005    AL  Adamsville  33.588437 -86.959727\n",
       "35006    AL       Adger  33.434277 -87.167455\n",
       "35007    AL    Keystone  33.236868 -86.812861\n",
       "35010    AL    New Site  32.941445 -85.951086"
      ]
     },
     "execution_count": 133,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "us_cities = None\n",
    "try:\n",
    "    csv_url = \"http://simplemaps.com/files/cities.csv\"\n",
    "    us_cities = pd.read_csv(csv_url, index_col=0)\n",
    "    us_cities = us_cities.head()\n",
    "except IOError as e:\n",
    "    print(e)\n",
    "us_cities"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "There are more options available, in particular regarding datetime format. Check out the [documentation](http://pandas.pydata.org/pandas-docs/stable/io.html) for more details."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Combining `DataFrame`s\n",
    "\n",
    "## SQL-like joins\n",
    "One powerful feature of pandas is it's ability to perform SQL-like joins on `DataFrame`s. Various types of joins are supported: inner joins, left/right outer joins and full joins. To illustrate this, let's start by creating a couple simple `DataFrame`s:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 134,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>state</th>\n",
       "      <th>city</th>\n",
       "      <th>lat</th>\n",
       "      <th>lng</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>CA</td>\n",
       "      <td>San Francisco</td>\n",
       "      <td>37.781334</td>\n",
       "      <td>-122.416728</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>NY</td>\n",
       "      <td>New York</td>\n",
       "      <td>40.705649</td>\n",
       "      <td>-74.008344</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>FL</td>\n",
       "      <td>Miami</td>\n",
       "      <td>25.791100</td>\n",
       "      <td>-80.320733</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>OH</td>\n",
       "      <td>Cleveland</td>\n",
       "      <td>41.473508</td>\n",
       "      <td>-81.739791</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>UT</td>\n",
       "      <td>Salt Lake City</td>\n",
       "      <td>40.755851</td>\n",
       "      <td>-111.896657</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  state            city        lat         lng\n",
       "0    CA   San Francisco  37.781334 -122.416728\n",
       "1    NY        New York  40.705649  -74.008344\n",
       "2    FL           Miami  25.791100  -80.320733\n",
       "3    OH       Cleveland  41.473508  -81.739791\n",
       "4    UT  Salt Lake City  40.755851 -111.896657"
      ]
     },
     "execution_count": 134,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "city_loc = pd.DataFrame(\n",
    "    [\n",
    "        [\"CA\", \"San Francisco\", 37.781334, -122.416728],\n",
    "        [\"NY\", \"New York\", 40.705649, -74.008344],\n",
    "        [\"FL\", \"Miami\", 25.791100, -80.320733],\n",
    "        [\"OH\", \"Cleveland\", 41.473508, -81.739791],\n",
    "        [\"UT\", \"Salt Lake City\", 40.755851, -111.896657]\n",
    "    ], columns=[\"state\", \"city\", \"lat\", \"lng\"])\n",
    "city_loc"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 135,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>population</th>\n",
       "      <th>city</th>\n",
       "      <th>state</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>808976</td>\n",
       "      <td>San Francisco</td>\n",
       "      <td>California</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>8363710</td>\n",
       "      <td>New York</td>\n",
       "      <td>New-York</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>413201</td>\n",
       "      <td>Miami</td>\n",
       "      <td>Florida</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>2242193</td>\n",
       "      <td>Houston</td>\n",
       "      <td>Texas</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   population           city       state\n",
       "3      808976  San Francisco  California\n",
       "4     8363710       New York    New-York\n",
       "5      413201          Miami     Florida\n",
       "6     2242193        Houston       Texas"
      ]
     },
     "execution_count": 135,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "city_pop = pd.DataFrame(\n",
    "    [\n",
    "        [808976, \"San Francisco\", \"California\"],\n",
    "        [8363710, \"New York\", \"New-York\"],\n",
    "        [413201, \"Miami\", \"Florida\"],\n",
    "        [2242193, \"Houston\", \"Texas\"]\n",
    "    ], index=[3,4,5,6], columns=[\"population\", \"city\", \"state\"])\n",
    "city_pop"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now let's join these `DataFrame`s using the `merge` function:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 136,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>state_x</th>\n",
       "      <th>city</th>\n",
       "      <th>lat</th>\n",
       "      <th>lng</th>\n",
       "      <th>population</th>\n",
       "      <th>state_y</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>CA</td>\n",
       "      <td>San Francisco</td>\n",
       "      <td>37.781334</td>\n",
       "      <td>-122.416728</td>\n",
       "      <td>808976</td>\n",
       "      <td>California</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>NY</td>\n",
       "      <td>New York</td>\n",
       "      <td>40.705649</td>\n",
       "      <td>-74.008344</td>\n",
       "      <td>8363710</td>\n",
       "      <td>New-York</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>FL</td>\n",
       "      <td>Miami</td>\n",
       "      <td>25.791100</td>\n",
       "      <td>-80.320733</td>\n",
       "      <td>413201</td>\n",
       "      <td>Florida</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  state_x           city        lat         lng  population     state_y\n",
       "0      CA  San Francisco  37.781334 -122.416728      808976  California\n",
       "1      NY       New York  40.705649  -74.008344     8363710    New-York\n",
       "2      FL          Miami  25.791100  -80.320733      413201     Florida"
      ]
     },
     "execution_count": 136,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.merge(left=city_loc, right=city_pop, on=\"city\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Note that both `DataFrame`s have a column named `state`, so in the result they got renamed to `state_x` and `state_y`.\n",
    "\n",
    "Also, note that Cleveland, Salt Lake City and Houston were dropped because they don't exist in *both* `DataFrame`s. This is the equivalent of a SQL `INNER JOIN`. If you want a `FULL OUTER JOIN`, where no city gets dropped and `NaN` values are added, you must specify `how=\"outer\"`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 137,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>state_x</th>\n",
       "      <th>city</th>\n",
       "      <th>lat</th>\n",
       "      <th>lng</th>\n",
       "      <th>population</th>\n",
       "      <th>state_y</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>CA</td>\n",
       "      <td>San Francisco</td>\n",
       "      <td>37.781334</td>\n",
       "      <td>-122.416728</td>\n",
       "      <td>808976</td>\n",
       "      <td>California</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>NY</td>\n",
       "      <td>New York</td>\n",
       "      <td>40.705649</td>\n",
       "      <td>-74.008344</td>\n",
       "      <td>8363710</td>\n",
       "      <td>New-York</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>FL</td>\n",
       "      <td>Miami</td>\n",
       "      <td>25.791100</td>\n",
       "      <td>-80.320733</td>\n",
       "      <td>413201</td>\n",
       "      <td>Florida</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>OH</td>\n",
       "      <td>Cleveland</td>\n",
       "      <td>41.473508</td>\n",
       "      <td>-81.739791</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>UT</td>\n",
       "      <td>Salt Lake City</td>\n",
       "      <td>40.755851</td>\n",
       "      <td>-111.896657</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>NaN</td>\n",
       "      <td>Houston</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>2242193</td>\n",
       "      <td>Texas</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  state_x            city        lat         lng  population     state_y\n",
       "0      CA   San Francisco  37.781334 -122.416728      808976  California\n",
       "1      NY        New York  40.705649  -74.008344     8363710    New-York\n",
       "2      FL           Miami  25.791100  -80.320733      413201     Florida\n",
       "3      OH       Cleveland  41.473508  -81.739791         NaN         NaN\n",
       "4      UT  Salt Lake City  40.755851 -111.896657         NaN         NaN\n",
       "5     NaN         Houston        NaN         NaN     2242193       Texas"
      ]
     },
     "execution_count": 137,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "all_cities = pd.merge(left=city_loc, right=city_pop, on=\"city\", how=\"outer\")\n",
    "all_cities"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Of course `LEFT OUTER JOIN` is also available by setting `how=\"left\"`: only the cities present in the left `DataFrame` end up in the result. Similarly, with `how=\"right\"` only cities in the right `DataFrame` appear in the result. For example:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 138,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>state_x</th>\n",
       "      <th>city</th>\n",
       "      <th>lat</th>\n",
       "      <th>lng</th>\n",
       "      <th>population</th>\n",
       "      <th>state_y</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>CA</td>\n",
       "      <td>San Francisco</td>\n",
       "      <td>37.781334</td>\n",
       "      <td>-122.416728</td>\n",
       "      <td>808976</td>\n",
       "      <td>California</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>NY</td>\n",
       "      <td>New York</td>\n",
       "      <td>40.705649</td>\n",
       "      <td>-74.008344</td>\n",
       "      <td>8363710</td>\n",
       "      <td>New-York</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>FL</td>\n",
       "      <td>Miami</td>\n",
       "      <td>25.791100</td>\n",
       "      <td>-80.320733</td>\n",
       "      <td>413201</td>\n",
       "      <td>Florida</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>NaN</td>\n",
       "      <td>Houston</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>2242193</td>\n",
       "      <td>Texas</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  state_x           city        lat         lng  population     state_y\n",
       "0      CA  San Francisco  37.781334 -122.416728      808976  California\n",
       "1      NY       New York  40.705649  -74.008344     8363710    New-York\n",
       "2      FL          Miami  25.791100  -80.320733      413201     Florida\n",
       "3     NaN        Houston        NaN         NaN     2242193       Texas"
      ]
     },
     "execution_count": 138,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.merge(left=city_loc, right=city_pop, on=\"city\", how=\"right\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If the key to join on is actually in one (or both) `DataFrame`'s index, you must use `left_index=True` and/or `right_index=True`. If the key column names differ, you must use `left_on` and `right_on`. For example:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 139,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>state_x</th>\n",
       "      <th>city</th>\n",
       "      <th>lat</th>\n",
       "      <th>lng</th>\n",
       "      <th>population</th>\n",
       "      <th>name</th>\n",
       "      <th>state_y</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>CA</td>\n",
       "      <td>San Francisco</td>\n",
       "      <td>37.781334</td>\n",
       "      <td>-122.416728</td>\n",
       "      <td>808976</td>\n",
       "      <td>San Francisco</td>\n",
       "      <td>California</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>NY</td>\n",
       "      <td>New York</td>\n",
       "      <td>40.705649</td>\n",
       "      <td>-74.008344</td>\n",
       "      <td>8363710</td>\n",
       "      <td>New York</td>\n",
       "      <td>New-York</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>FL</td>\n",
       "      <td>Miami</td>\n",
       "      <td>25.791100</td>\n",
       "      <td>-80.320733</td>\n",
       "      <td>413201</td>\n",
       "      <td>Miami</td>\n",
       "      <td>Florida</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  state_x           city        lat         lng  population           name  \\\n",
       "0      CA  San Francisco  37.781334 -122.416728      808976  San Francisco   \n",
       "1      NY       New York  40.705649  -74.008344     8363710       New York   \n",
       "2      FL          Miami  25.791100  -80.320733      413201          Miami   \n",
       "\n",
       "      state_y  \n",
       "0  California  \n",
       "1    New-York  \n",
       "2     Florida  "
      ]
     },
     "execution_count": 139,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "city_pop2 = city_pop.copy()\n",
    "city_pop2.columns = [\"population\", \"name\", \"state\"]\n",
    "pd.merge(left=city_loc, right=city_pop2, left_on=\"city\", right_on=\"name\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Concatenation\n",
    "Rather than joining `DataFrame`s, we may just want to concatenate them. That's what `concat` is for:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 140,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>city</th>\n",
       "      <th>lat</th>\n",
       "      <th>lng</th>\n",
       "      <th>population</th>\n",
       "      <th>state</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>San Francisco</td>\n",
       "      <td>37.781334</td>\n",
       "      <td>-122.416728</td>\n",
       "      <td>NaN</td>\n",
       "      <td>CA</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>New York</td>\n",
       "      <td>40.705649</td>\n",
       "      <td>-74.008344</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NY</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>Miami</td>\n",
       "      <td>25.791100</td>\n",
       "      <td>-80.320733</td>\n",
       "      <td>NaN</td>\n",
       "      <td>FL</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>Cleveland</td>\n",
       "      <td>41.473508</td>\n",
       "      <td>-81.739791</td>\n",
       "      <td>NaN</td>\n",
       "      <td>OH</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>Salt Lake City</td>\n",
       "      <td>40.755851</td>\n",
       "      <td>-111.896657</td>\n",
       "      <td>NaN</td>\n",
       "      <td>UT</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>San Francisco</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>808976</td>\n",
       "      <td>California</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>New York</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>8363710</td>\n",
       "      <td>New-York</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>Miami</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>413201</td>\n",
       "      <td>Florida</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>Houston</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>2242193</td>\n",
       "      <td>Texas</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "             city        lat         lng  population       state\n",
       "0   San Francisco  37.781334 -122.416728         NaN          CA\n",
       "1        New York  40.705649  -74.008344         NaN          NY\n",
       "2           Miami  25.791100  -80.320733         NaN          FL\n",
       "3       Cleveland  41.473508  -81.739791         NaN          OH\n",
       "4  Salt Lake City  40.755851 -111.896657         NaN          UT\n",
       "3   San Francisco        NaN         NaN      808976  California\n",
       "4        New York        NaN         NaN     8363710    New-York\n",
       "5           Miami        NaN         NaN      413201     Florida\n",
       "6         Houston        NaN         NaN     2242193       Texas"
      ]
     },
     "execution_count": 140,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "result_concat = pd.concat([city_loc, city_pop])\n",
    "result_concat"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Note that this operation aligned the data horizontally (by columns) but not vertically (by rows). In this example, we end up with multiple rows having the same index (eg. 3). Pandas handles this rather gracefully:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 141,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>city</th>\n",
       "      <th>lat</th>\n",
       "      <th>lng</th>\n",
       "      <th>population</th>\n",
       "      <th>state</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>Cleveland</td>\n",
       "      <td>41.473508</td>\n",
       "      <td>-81.739791</td>\n",
       "      <td>NaN</td>\n",
       "      <td>OH</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>San Francisco</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>808976</td>\n",
       "      <td>California</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "            city        lat        lng  population       state\n",
       "3      Cleveland  41.473508 -81.739791         NaN          OH\n",
       "3  San Francisco        NaN        NaN      808976  California"
      ]
     },
     "execution_count": 141,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "result_concat.loc[3]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Or you can tell pandas to just ignore the index:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 142,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>city</th>\n",
       "      <th>lat</th>\n",
       "      <th>lng</th>\n",
       "      <th>population</th>\n",
       "      <th>state</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>San Francisco</td>\n",
       "      <td>37.781334</td>\n",
       "      <td>-122.416728</td>\n",
       "      <td>NaN</td>\n",
       "      <td>CA</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>New York</td>\n",
       "      <td>40.705649</td>\n",
       "      <td>-74.008344</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NY</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>Miami</td>\n",
       "      <td>25.791100</td>\n",
       "      <td>-80.320733</td>\n",
       "      <td>NaN</td>\n",
       "      <td>FL</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>Cleveland</td>\n",
       "      <td>41.473508</td>\n",
       "      <td>-81.739791</td>\n",
       "      <td>NaN</td>\n",
       "      <td>OH</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>Salt Lake City</td>\n",
       "      <td>40.755851</td>\n",
       "      <td>-111.896657</td>\n",
       "      <td>NaN</td>\n",
       "      <td>UT</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>San Francisco</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>808976</td>\n",
       "      <td>California</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>New York</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>8363710</td>\n",
       "      <td>New-York</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>Miami</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>413201</td>\n",
       "      <td>Florida</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>Houston</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>2242193</td>\n",
       "      <td>Texas</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "             city        lat         lng  population       state\n",
       "0   San Francisco  37.781334 -122.416728         NaN          CA\n",
       "1        New York  40.705649  -74.008344         NaN          NY\n",
       "2           Miami  25.791100  -80.320733         NaN          FL\n",
       "3       Cleveland  41.473508  -81.739791         NaN          OH\n",
       "4  Salt Lake City  40.755851 -111.896657         NaN          UT\n",
       "5   San Francisco        NaN         NaN      808976  California\n",
       "6        New York        NaN         NaN     8363710    New-York\n",
       "7           Miami        NaN         NaN      413201     Florida\n",
       "8         Houston        NaN         NaN     2242193       Texas"
      ]
     },
     "execution_count": 142,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.concat([city_loc, city_pop], ignore_index=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Notice that when a column does not exist in a `DataFrame`, it acts as if it was filled with `NaN` values. If we set `join=\"inner\"`, then only columns that exist in *both* `DataFrame`s are returned:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 143,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>city</th>\n",
       "      <th>state</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>San Francisco</td>\n",
       "      <td>CA</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>New York</td>\n",
       "      <td>NY</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>Miami</td>\n",
       "      <td>FL</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>Cleveland</td>\n",
       "      <td>OH</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>Salt Lake City</td>\n",
       "      <td>UT</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>San Francisco</td>\n",
       "      <td>California</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>New York</td>\n",
       "      <td>New-York</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>Miami</td>\n",
       "      <td>Florida</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>Houston</td>\n",
       "      <td>Texas</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "             city       state\n",
       "0   San Francisco          CA\n",
       "1        New York          NY\n",
       "2           Miami          FL\n",
       "3       Cleveland          OH\n",
       "4  Salt Lake City          UT\n",
       "3   San Francisco  California\n",
       "4        New York    New-York\n",
       "5           Miami     Florida\n",
       "6         Houston       Texas"
      ]
     },
     "execution_count": 143,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.concat([city_loc, city_pop], join=\"inner\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can concatenate `DataFrame`s horizontally instead of vertically by setting `axis=1`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 144,
   "metadata": {
    "collapsed": false,
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>state</th>\n",
       "      <th>city</th>\n",
       "      <th>lat</th>\n",
       "      <th>lng</th>\n",
       "      <th>population</th>\n",
       "      <th>city</th>\n",
       "      <th>state</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>CA</td>\n",
       "      <td>San Francisco</td>\n",
       "      <td>37.781334</td>\n",
       "      <td>-122.416728</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>NY</td>\n",
       "      <td>New York</td>\n",
       "      <td>40.705649</td>\n",
       "      <td>-74.008344</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>FL</td>\n",
       "      <td>Miami</td>\n",
       "      <td>25.791100</td>\n",
       "      <td>-80.320733</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>OH</td>\n",
       "      <td>Cleveland</td>\n",
       "      <td>41.473508</td>\n",
       "      <td>-81.739791</td>\n",
       "      <td>808976</td>\n",
       "      <td>San Francisco</td>\n",
       "      <td>California</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>UT</td>\n",
       "      <td>Salt Lake City</td>\n",
       "      <td>40.755851</td>\n",
       "      <td>-111.896657</td>\n",
       "      <td>8363710</td>\n",
       "      <td>New York</td>\n",
       "      <td>New-York</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>413201</td>\n",
       "      <td>Miami</td>\n",
       "      <td>Florida</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>2242193</td>\n",
       "      <td>Houston</td>\n",
       "      <td>Texas</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  state            city        lat         lng  population           city  \\\n",
       "0    CA   San Francisco  37.781334 -122.416728         NaN            NaN   \n",
       "1    NY        New York  40.705649  -74.008344         NaN            NaN   \n",
       "2    FL           Miami  25.791100  -80.320733         NaN            NaN   \n",
       "3    OH       Cleveland  41.473508  -81.739791      808976  San Francisco   \n",
       "4    UT  Salt Lake City  40.755851 -111.896657     8363710       New York   \n",
       "5   NaN             NaN        NaN         NaN      413201          Miami   \n",
       "6   NaN             NaN        NaN         NaN     2242193        Houston   \n",
       "\n",
       "        state  \n",
       "0         NaN  \n",
       "1         NaN  \n",
       "2         NaN  \n",
       "3  California  \n",
       "4    New-York  \n",
       "5     Florida  \n",
       "6       Texas  "
      ]
     },
     "execution_count": 144,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.concat([city_loc, city_pop], axis=1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In this case it really does not make much sense because the indices do not align well (eg. Cleveland and San Francisco end up on the same row, because they shared the index label `3`). So let's reindex the `DataFrame`s by city name before concatenating:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 145,
   "metadata": {
    "collapsed": false,
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>state</th>\n",
       "      <th>lat</th>\n",
       "      <th>lng</th>\n",
       "      <th>population</th>\n",
       "      <th>state</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>Cleveland</th>\n",
       "      <td>OH</td>\n",
       "      <td>41.473508</td>\n",
       "      <td>-81.739791</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Houston</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>2242193</td>\n",
       "      <td>Texas</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Miami</th>\n",
       "      <td>FL</td>\n",
       "      <td>25.791100</td>\n",
       "      <td>-80.320733</td>\n",
       "      <td>413201</td>\n",
       "      <td>Florida</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>New York</th>\n",
       "      <td>NY</td>\n",
       "      <td>40.705649</td>\n",
       "      <td>-74.008344</td>\n",
       "      <td>8363710</td>\n",
       "      <td>New-York</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Salt Lake City</th>\n",
       "      <td>UT</td>\n",
       "      <td>40.755851</td>\n",
       "      <td>-111.896657</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>San Francisco</th>\n",
       "      <td>CA</td>\n",
       "      <td>37.781334</td>\n",
       "      <td>-122.416728</td>\n",
       "      <td>808976</td>\n",
       "      <td>California</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "               state        lat         lng  population       state\n",
       "Cleveland         OH  41.473508  -81.739791         NaN         NaN\n",
       "Houston          NaN        NaN         NaN     2242193       Texas\n",
       "Miami             FL  25.791100  -80.320733      413201     Florida\n",
       "New York          NY  40.705649  -74.008344     8363710    New-York\n",
       "Salt Lake City    UT  40.755851 -111.896657         NaN         NaN\n",
       "San Francisco     CA  37.781334 -122.416728      808976  California"
      ]
     },
     "execution_count": 145,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.concat([city_loc.set_index(\"city\"), city_pop.set_index(\"city\")], axis=1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This looks a lot like a `FULL OUTER JOIN`, except that the `state` columns were not renamed to `state_x` and `state_y`, and the `city` column is now the index."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The `append` method is a useful shorthand for concatenating `DataFrame`s vertically:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 146,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>city</th>\n",
       "      <th>lat</th>\n",
       "      <th>lng</th>\n",
       "      <th>population</th>\n",
       "      <th>state</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>San Francisco</td>\n",
       "      <td>37.781334</td>\n",
       "      <td>-122.416728</td>\n",
       "      <td>NaN</td>\n",
       "      <td>CA</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>New York</td>\n",
       "      <td>40.705649</td>\n",
       "      <td>-74.008344</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NY</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>Miami</td>\n",
       "      <td>25.791100</td>\n",
       "      <td>-80.320733</td>\n",
       "      <td>NaN</td>\n",
       "      <td>FL</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>Cleveland</td>\n",
       "      <td>41.473508</td>\n",
       "      <td>-81.739791</td>\n",
       "      <td>NaN</td>\n",
       "      <td>OH</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>Salt Lake City</td>\n",
       "      <td>40.755851</td>\n",
       "      <td>-111.896657</td>\n",
       "      <td>NaN</td>\n",
       "      <td>UT</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>San Francisco</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>808976</td>\n",
       "      <td>California</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>New York</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>8363710</td>\n",
       "      <td>New-York</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>Miami</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>413201</td>\n",
       "      <td>Florida</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>Houston</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>2242193</td>\n",
       "      <td>Texas</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "             city        lat         lng  population       state\n",
       "0   San Francisco  37.781334 -122.416728         NaN          CA\n",
       "1        New York  40.705649  -74.008344         NaN          NY\n",
       "2           Miami  25.791100  -80.320733         NaN          FL\n",
       "3       Cleveland  41.473508  -81.739791         NaN          OH\n",
       "4  Salt Lake City  40.755851 -111.896657         NaN          UT\n",
       "3   San Francisco        NaN         NaN      808976  California\n",
       "4        New York        NaN         NaN     8363710    New-York\n",
       "5           Miami        NaN         NaN      413201     Florida\n",
       "6         Houston        NaN         NaN     2242193       Texas"
      ]
     },
     "execution_count": 146,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "city_loc.append(city_pop)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As always in pandas, the `append` method does *not* actually modify `city_loc`: it works on a copy and returns the modified copy."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Categories\n",
    "It is quite frequent to have values that represent categories, for example `1` for female and `2` for male, or `\"A\"` for Good, `\"B\"` for Average, `\"C\"` for Bad. These categorical values can be hard to read and cumbersome to handle, but fortunately pandas makes it easy. To illustrate this, let's take the `city_pop` `DataFrame` we created earlier, and add a column that represents a category:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 147,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>population</th>\n",
       "      <th>city</th>\n",
       "      <th>state</th>\n",
       "      <th>eco_code</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>808976</td>\n",
       "      <td>San Francisco</td>\n",
       "      <td>California</td>\n",
       "      <td>17</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>8363710</td>\n",
       "      <td>New York</td>\n",
       "      <td>New-York</td>\n",
       "      <td>17</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>413201</td>\n",
       "      <td>Miami</td>\n",
       "      <td>Florida</td>\n",
       "      <td>34</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>2242193</td>\n",
       "      <td>Houston</td>\n",
       "      <td>Texas</td>\n",
       "      <td>20</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   population           city       state  eco_code\n",
       "3      808976  San Francisco  California        17\n",
       "4     8363710       New York    New-York        17\n",
       "5      413201          Miami     Florida        34\n",
       "6     2242193        Houston       Texas        20"
      ]
     },
     "execution_count": 147,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "city_eco = city_pop.copy()\n",
    "city_eco[\"eco_code\"] = [17, 17, 34, 20]\n",
    "city_eco"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Right now the `eco_code` column is full of apparently meaningless codes. Let's fix that. First, we will create a new categorical column based on the `eco_code`s:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 148,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Int64Index([17, 20, 34], dtype='int64')"
      ]
     },
     "execution_count": 148,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "city_eco[\"economy\"] = city_eco[\"eco_code\"].astype('category')\n",
    "city_eco[\"economy\"].cat.categories"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now we can give each category a meaningful name:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 149,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>population</th>\n",
       "      <th>city</th>\n",
       "      <th>state</th>\n",
       "      <th>eco_code</th>\n",
       "      <th>economy</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>808976</td>\n",
       "      <td>San Francisco</td>\n",
       "      <td>California</td>\n",
       "      <td>17</td>\n",
       "      <td>Finance</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>8363710</td>\n",
       "      <td>New York</td>\n",
       "      <td>New-York</td>\n",
       "      <td>17</td>\n",
       "      <td>Finance</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>413201</td>\n",
       "      <td>Miami</td>\n",
       "      <td>Florida</td>\n",
       "      <td>34</td>\n",
       "      <td>Tourism</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>2242193</td>\n",
       "      <td>Houston</td>\n",
       "      <td>Texas</td>\n",
       "      <td>20</td>\n",
       "      <td>Energy</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   population           city       state  eco_code  economy\n",
       "3      808976  San Francisco  California        17  Finance\n",
       "4     8363710       New York    New-York        17  Finance\n",
       "5      413201          Miami     Florida        34  Tourism\n",
       "6     2242193        Houston       Texas        20   Energy"
      ]
     },
     "execution_count": 149,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "city_eco[\"economy\"].cat.categories = [\"Finance\", \"Energy\", \"Tourism\"]\n",
    "city_eco"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Note that categorical values are sorted according to their categorical order, *not* their alphabetical order:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 150,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>population</th>\n",
       "      <th>city</th>\n",
       "      <th>state</th>\n",
       "      <th>eco_code</th>\n",
       "      <th>economy</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>413201</td>\n",
       "      <td>Miami</td>\n",
       "      <td>Florida</td>\n",
       "      <td>34</td>\n",
       "      <td>Tourism</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>2242193</td>\n",
       "      <td>Houston</td>\n",
       "      <td>Texas</td>\n",
       "      <td>20</td>\n",
       "      <td>Energy</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>8363710</td>\n",
       "      <td>New York</td>\n",
       "      <td>New-York</td>\n",
       "      <td>17</td>\n",
       "      <td>Finance</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>808976</td>\n",
       "      <td>San Francisco</td>\n",
       "      <td>California</td>\n",
       "      <td>17</td>\n",
       "      <td>Finance</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   population           city       state  eco_code  economy\n",
       "5      413201          Miami     Florida        34  Tourism\n",
       "6     2242193        Houston       Texas        20   Energy\n",
       "4     8363710       New York    New-York        17  Finance\n",
       "3      808976  San Francisco  California        17  Finance"
      ]
     },
     "execution_count": 150,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "city_eco.sort_values(by=\"economy\", ascending=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "# What next?\n",
    "As you probably noticed by now, pandas is quite a large library with *many* features. Although we went through the most important features, there is still a lot to discover. Probably the best way to learn more is to get your hands dirty with some real-life data. It is also a good idea to go through pandas' excellent [documentation](http://pandas.pydata.org/pandas-docs/stable/index.html), in particular the [Cookbook](http://pandas.pydata.org/pandas-docs/stable/cookbook.html)."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 2",
   "language": "python",
   "name": "python2"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.11"
  },
  "toc": {
   "toc_cell": false,
   "toc_number_sections": true,
   "toc_section_display": "none",
   "toc_threshold": 6,
   "toc_window_display": true
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
