diff --git a/pandas/03.00-Introduction-to-Pandas.ipynb b/pandas/03.00-Introduction-to-Pandas.ipynb new file mode 100644 index 0000000..3467314 --- /dev/null +++ b/pandas/03.00-Introduction-to-Pandas.ipynb @@ -0,0 +1,164 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "\n", + "*This notebook contains an excerpt from the [Python Data Science Handbook](http://shop.oreilly.com/product/0636920034919.do) by Jake VanderPlas; the content is available [on GitHub](https://github.com/jakevdp/PythonDataScienceHandbook).*\n", + "\n", + "*The text is released under the [CC-BY-NC-ND license](https://creativecommons.org/licenses/by-nc-nd/3.0/us/legalcode), and code is released under the [MIT license](https://opensource.org/licenses/MIT). If you find this content useful, please consider supporting the work by [buying the book](http://shop.oreilly.com/product/0636920034919.do)!*\n", + "\n", + "*No changes were made to the contents of this notebook from the original.*" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "< [Structured Data: NumPy's Structured Arrays](02.09-Structured-Data-NumPy.ipynb) | [Contents](Index.ipynb) | [Introducing Pandas Objects](03.01-Introducing-Pandas-Objects.ipynb) >" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Data Manipulation with Pandas" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In the previous chapter, we dove into detail on NumPy and its ``ndarray`` object, which provides efficient storage and manipulation of dense typed arrays in Python.\n", + "Here we'll build on this knowledge by looking in detail at the data structures provided by the Pandas library.\n", + "Pandas is a newer package built on top of NumPy, and provides an efficient implementation of a ``DataFrame``.\n", + "``DataFrame``s are essentially multidimensional arrays with attached row and column labels, and often with heterogeneous types and/or missing data.\n", + "As well as offering a convenient storage interface for labeled data, Pandas implements a number of powerful data operations familiar to users of both database frameworks and spreadsheet programs.\n", + "\n", + "As we saw, NumPy's ``ndarray`` data structure provides essential features for the type of clean, well-organized data typically seen in numerical computing tasks.\n", + "While it serves this purpose very well, its limitations become clear when we need more flexibility (e.g., attaching labels to data, working with missing data, etc.) and when attempting operations that do not map well to element-wise broadcasting (e.g., groupings, pivots, etc.), each of which is an important piece of analyzing the less structured data available in many forms in the world around us.\n", + "Pandas, and in particular its ``Series`` and ``DataFrame`` objects, builds on the NumPy array structure and provides efficient access to these sorts of \"data munging\" tasks that occupy much of a data scientist's time.\n", + "\n", + "In this chapter, we will focus on the mechanics of using ``Series``, ``DataFrame``, and related structures effectively.\n", + "We will use examples drawn from real datasets where appropriate, but these examples are not necessarily the focus." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Installing and Using Pandas\n", + "\n", + "Installation of Pandas on your system requires NumPy to be installed, and if building the library from source, requires the appropriate tools to compile the C and Cython sources on which Pandas is built.\n", + "Details on this installation can be found in the [Pandas documentation](http://pandas.pydata.org/).\n", + "If you followed the advice outlined in the [Preface](00.00-Preface.ipynb) and used the Anaconda stack, you already have Pandas installed.\n", + "\n", + "Once Pandas is installed, you can import it and check the version:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'0.18.1'" + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import pandas\n", + "pandas.__version__" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Just as we generally import NumPy under the alias ``np``, we will import Pandas under the alias ``pd``:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import pandas as pd" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This import convention will be used throughout the remainder of this book." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Reminder about Built-In Documentation\n", + "\n", + "As you read through this chapter, don't forget that IPython gives you the ability to quickly explore the contents of a package (by using the tab-completion feature) as well as the documentation of various functions (using the ``?`` character). (Refer back to [Help and Documentation in IPython](01.01-Help-And-Documentation.ipynb) if you need a refresher on this.)\n", + "\n", + "For example, to display all the contents of the pandas namespace, you can type\n", + "\n", + "```ipython\n", + "In [3]: pd.\n", + "```\n", + "\n", + "And to display Pandas's built-in documentation, you can use this:\n", + "\n", + "```ipython\n", + "In [4]: pd?\n", + "```\n", + "\n", + "More detailed documentation, along with tutorials and other resources, can be found at http://pandas.pydata.org/." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "< [Structured Data: NumPy's Structured Arrays](02.09-Structured-Data-NumPy.ipynb) | [Contents](Index.ipynb) | [Introducing Pandas Objects](03.01-Introducing-Pandas-Objects.ipynb) >" + ] + } + ], + "metadata": { + "anaconda-cloud": {}, + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.4.3" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/pandas/03.01-Introducing-Pandas-Objects.ipynb b/pandas/03.01-Introducing-Pandas-Objects.ipynb new file mode 100644 index 0000000..aa7780a --- /dev/null +++ b/pandas/03.01-Introducing-Pandas-Objects.ipynb @@ -0,0 +1,1560 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "\n", + "*This notebook contains an excerpt from the [Python Data Science Handbook](http://shop.oreilly.com/product/0636920034919.do) by Jake VanderPlas; the content is available [on GitHub](https://github.com/jakevdp/PythonDataScienceHandbook).*\n", + "\n", + "*The text is released under the [CC-BY-NC-ND license](https://creativecommons.org/licenses/by-nc-nd/3.0/us/legalcode), and code is released under the [MIT license](https://opensource.org/licenses/MIT). If you find this content useful, please consider supporting the work by [buying the book](http://shop.oreilly.com/product/0636920034919.do)!*\n", + "\n", + "*No changes were made to the contents of this notebook from the original.*" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "< [Data Manipulation with Pandas](03.00-Introduction-to-Pandas.ipynb) | [Contents](Index.ipynb) | [Data Indexing and Selection](03.02-Data-Indexing-and-Selection.ipynb) >" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Introducing Pandas Objects" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "At the very basic level, Pandas objects can be thought of as enhanced versions of NumPy structured arrays in which the rows and columns are identified with labels rather than simple integer indices.\n", + "As we will see during the course of this chapter, Pandas provides a host of useful tools, methods, and functionality on top of the basic data structures, but nearly everything that follows will require an understanding of what these structures are.\n", + "Thus, before we go any further, let's introduce these three fundamental Pandas data structures: the ``Series``, ``DataFrame``, and ``Index``.\n", + "\n", + "We will start our code sessions with the standard NumPy and Pandas imports:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import pandas as pd" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## The Pandas Series Object\n", + "\n", + "A Pandas ``Series`` is a one-dimensional array of indexed data.\n", + "It can be created from a list or array as follows:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "0 0.25\n", + "1 0.50\n", + "2 0.75\n", + "3 1.00\n", + "dtype: float64" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data = pd.Series([0.25, 0.5, 0.75, 1.0])\n", + "data" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "As we see in the output, the ``Series`` wraps both a sequence of values and a sequence of indices, which we can access with the ``values`` and ``index`` attributes.\n", + "The ``values`` are simply a familiar NumPy array:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([ 0.25, 0.5 , 0.75, 1. ])" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data.values" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The ``index`` is an array-like object of type ``pd.Index``, which we'll discuss in more detail momentarily." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "RangeIndex(start=0, stop=4, step=1)" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data.index" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Like with a NumPy array, data can be accessed by the associated index via the familiar Python square-bracket notation:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "0.5" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data[1]" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "1 0.50\n", + "2 0.75\n", + "dtype: float64" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data[1:3]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "As we will see, though, the Pandas ``Series`` is much more general and flexible than the one-dimensional NumPy array that it emulates." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### ``Series`` as generalized NumPy array" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "From what we've seen so far, it may look like the ``Series`` object is basically interchangeable with a one-dimensional NumPy array.\n", + "The essential difference is the presence of the index: while the Numpy Array has an *implicitly defined* integer index used to access the values, the Pandas ``Series`` has an *explicitly defined* index associated with the values.\n", + "\n", + "This explicit index definition gives the ``Series`` object additional capabilities. For example, the index need not be an integer, but can consist of values of any desired type.\n", + "For example, if we wish, we can use strings as an index:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "a 0.25\n", + "b 0.50\n", + "c 0.75\n", + "d 1.00\n", + "dtype: float64" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data = pd.Series([0.25, 0.5, 0.75, 1.0],\n", + " index=['a', 'b', 'c', 'd'])\n", + "data" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And the item access works as expected:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "0.5" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data['b']" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can even use non-contiguous or non-sequential indices:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "2 0.25\n", + "5 0.50\n", + "3 0.75\n", + "7 1.00\n", + "dtype: float64" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data = pd.Series([0.25, 0.5, 0.75, 1.0],\n", + " index=[2, 5, 3, 7])\n", + "data" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "0.5" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data[5]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Series as specialized dictionary\n", + "\n", + "In this way, you can think of a Pandas ``Series`` a bit like a specialization of a Python dictionary.\n", + "A dictionary is a structure that maps arbitrary keys to a set of arbitrary values, and a ``Series`` is a structure which maps typed keys to a set of typed values.\n", + "This typing is important: just as the type-specific compiled code behind a NumPy array makes it more efficient than a Python list for certain operations, the type information of a Pandas ``Series`` makes it much more efficient than Python dictionaries for certain operations.\n", + "\n", + "The ``Series``-as-dictionary analogy can be made even more clear by constructing a ``Series`` object directly from a Python dictionary:" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "California 38332521\n", + "Florida 19552860\n", + "Illinois 12882135\n", + "New York 19651127\n", + "Texas 26448193\n", + "dtype: int64" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "population_dict = {'California': 38332521,\n", + " 'Texas': 26448193,\n", + " 'New York': 19651127,\n", + " 'Florida': 19552860,\n", + " 'Illinois': 12882135}\n", + "population = pd.Series(population_dict)\n", + "population" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "By default, a ``Series`` will be created where the index is drawn from the sorted keys.\n", + "From here, typical dictionary-style item access can be performed:" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "38332521" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "population['California']" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Unlike a dictionary, though, the ``Series`` also supports array-style operations such as slicing:" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "California 38332521\n", + "Florida 19552860\n", + "Illinois 12882135\n", + "dtype: int64" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "population['California':'Illinois']" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We'll discuss some of the quirks of Pandas indexing and slicing in [Data Indexing and Selection](03.02-Data-Indexing-and-Selection.ipynb)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Constructing Series objects\n", + "\n", + "We've already seen a few ways of constructing a Pandas ``Series`` from scratch; all of them are some version of the following:\n", + "\n", + "```python\n", + ">>> pd.Series(data, index=index)\n", + "```\n", + "\n", + "where ``index`` is an optional argument, and ``data`` can be one of many entities.\n", + "\n", + "For example, ``data`` can be a list or NumPy array, in which case ``index`` defaults to an integer sequence:" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "0 2\n", + "1 4\n", + "2 6\n", + "dtype: int64" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pd.Series([2, 4, 6])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "``data`` can be a scalar, which is repeated to fill the specified index:" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "100 5\n", + "200 5\n", + "300 5\n", + "dtype: int64" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pd.Series(5, index=[100, 200, 300])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "``data`` can be a dictionary, in which ``index`` defaults to the sorted dictionary keys:" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "1 b\n", + "2 a\n", + "3 c\n", + "dtype: object" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pd.Series({2:'a', 1:'b', 3:'c'})" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In each case, the index can be explicitly set if a different result is preferred:" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "3 c\n", + "2 a\n", + "dtype: object" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pd.Series({2:'a', 1:'b', 3:'c'}, index=[3, 2])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Notice that in this case, the ``Series`` is populated only with the explicitly identified keys." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## The Pandas DataFrame Object\n", + "\n", + "The next fundamental structure in Pandas is the ``DataFrame``.\n", + "Like the ``Series`` object discussed in the previous section, the ``DataFrame`` can be thought of either as a generalization of a NumPy array, or as a specialization of a Python dictionary.\n", + "We'll now take a look at each of these perspectives." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### DataFrame as a generalized NumPy array\n", + "If a ``Series`` is an analog of a one-dimensional array with flexible indices, a ``DataFrame`` is an analog of a two-dimensional array with both flexible row indices and flexible column names.\n", + "Just as you might think of a two-dimensional array as an ordered sequence of aligned one-dimensional columns, you can think of a ``DataFrame`` as a sequence of aligned ``Series`` objects.\n", + "Here, by \"aligned\" we mean that they share the same index.\n", + "\n", + "To demonstrate this, let's first construct a new ``Series`` listing the area of each of the five states discussed in the previous section:" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "California 423967\n", + "Florida 170312\n", + "Illinois 149995\n", + "New York 141297\n", + "Texas 695662\n", + "dtype: int64" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "area_dict = {'California': 423967, 'Texas': 695662, 'New York': 141297,\n", + " 'Florida': 170312, 'Illinois': 149995}\n", + "area = pd.Series(area_dict)\n", + "area" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now that we have this along with the ``population`` Series from before, we can use a dictionary to construct a single two-dimensional object containing this information:" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
areapopulation
California42396738332521
Florida17031219552860
Illinois14999512882135
New York14129719651127
Texas69566226448193
\n", + "
" + ], + "text/plain": [ + " area population\n", + "California 423967 38332521\n", + "Florida 170312 19552860\n", + "Illinois 149995 12882135\n", + "New York 141297 19651127\n", + "Texas 695662 26448193" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "states = pd.DataFrame({'population': population,\n", + " 'area': area})\n", + "states" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Like the ``Series`` object, the ``DataFrame`` has an ``index`` attribute that gives access to the index labels:" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Index(['California', 'Florida', 'Illinois', 'New York', 'Texas'], dtype='object')" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "states.index" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Additionally, the ``DataFrame`` has a ``columns`` attribute, which is an ``Index`` object holding the column labels:" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Index(['area', 'population'], dtype='object')" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "states.columns" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Thus the ``DataFrame`` can be thought of as a generalization of a two-dimensional NumPy array, where both the rows and columns have a generalized index for accessing the data." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### DataFrame as specialized dictionary\n", + "\n", + "Similarly, we can also think of a ``DataFrame`` as a specialization of a dictionary.\n", + "Where a dictionary maps a key to a value, a ``DataFrame`` maps a column name to a ``Series`` of column data.\n", + "For example, asking for the ``'area'`` attribute returns the ``Series`` object containing the areas we saw earlier:" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "California 423967\n", + "Florida 170312\n", + "Illinois 149995\n", + "New York 141297\n", + "Texas 695662\n", + "Name: area, dtype: int64" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "states['area']" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Notice the potential point of confusion here: in a two-dimesnional NumPy array, ``data[0]`` will return the first *row*. For a ``DataFrame``, ``data['col0']`` will return the first *column*.\n", + "Because of this, it is probably better to think about ``DataFrame``s as generalized dictionaries rather than generalized arrays, though both ways of looking at the situation can be useful.\n", + "We'll explore more flexible means of indexing ``DataFrame``s in [Data Indexing and Selection](03.02-Data-Indexing-and-Selection.ipynb)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Constructing DataFrame objects\n", + "\n", + "A Pandas ``DataFrame`` can be constructed in a variety of ways.\n", + "Here we'll give several examples." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### From a single Series object\n", + "\n", + "A ``DataFrame`` is a collection of ``Series`` objects, and a single-column ``DataFrame`` can be constructed from a single ``Series``:" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
population
California38332521
Florida19552860
Illinois12882135
New York19651127
Texas26448193
\n", + "
" + ], + "text/plain": [ + " population\n", + "California 38332521\n", + "Florida 19552860\n", + "Illinois 12882135\n", + "New York 19651127\n", + "Texas 26448193" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pd.DataFrame(population, columns=['population'])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### From a list of dicts\n", + "\n", + "Any list of dictionaries can be made into a ``DataFrame``.\n", + "We'll use a simple list comprehension to create some data:" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ab
000
112
224
\n", + "
" + ], + "text/plain": [ + " a b\n", + "0 0 0\n", + "1 1 2\n", + "2 2 4" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data = [{'a': i, 'b': 2 * i}\n", + " for i in range(3)]\n", + "pd.DataFrame(data)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Even if some keys in the dictionary are missing, Pandas will fill them in with ``NaN`` (i.e., \"not a number\") values:" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
abc
01.02NaN
1NaN34.0
\n", + "
" + ], + "text/plain": [ + " a b c\n", + "0 1.0 2 NaN\n", + "1 NaN 3 4.0" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pd.DataFrame([{'a': 1, 'b': 2}, {'b': 3, 'c': 4}])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### From a dictionary of Series objects\n", + "\n", + "As we saw before, a ``DataFrame`` can be constructed from a dictionary of ``Series`` objects as well:" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
areapopulation
California42396738332521
Florida17031219552860
Illinois14999512882135
New York14129719651127
Texas69566226448193
\n", + "
" + ], + "text/plain": [ + " area population\n", + "California 423967 38332521\n", + "Florida 170312 19552860\n", + "Illinois 149995 12882135\n", + "New York 141297 19651127\n", + "Texas 695662 26448193" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pd.DataFrame({'population': population,\n", + " 'area': area})" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### From a two-dimensional NumPy array\n", + "\n", + "Given a two-dimensional array of data, we can create a ``DataFrame`` with any specified column and index names.\n", + "If omitted, an integer index will be used for each:" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
foobar
a0.8652570.213169
b0.4427590.108267
c0.0471100.905718
\n", + "
" + ], + "text/plain": [ + " foo bar\n", + "a 0.865257 0.213169\n", + "b 0.442759 0.108267\n", + "c 0.047110 0.905718" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pd.DataFrame(np.random.rand(3, 2),\n", + " columns=['foo', 'bar'],\n", + " index=['a', 'b', 'c'])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### From a NumPy structured array\n", + "\n", + "We covered structured arrays in [Structured Data: NumPy's Structured Arrays](02.09-Structured-Data-NumPy.ipynb).\n", + "A Pandas ``DataFrame`` operates much like a structured array, and can be created directly from one:" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([(0, 0.0), (0, 0.0), (0, 0.0)], \n", + " dtype=[('A', '\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
AB
000.0
100.0
200.0
\n", + "" + ], + "text/plain": [ + " A B\n", + "0 0 0.0\n", + "1 0 0.0\n", + "2 0 0.0" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pd.DataFrame(A)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## The Pandas Index Object\n", + "\n", + "We have seen here that both the ``Series`` and ``DataFrame`` objects contain an explicit *index* that lets you reference and modify data.\n", + "This ``Index`` object is an interesting structure in itself, and it can be thought of either as an *immutable array* or as an *ordered set* (technically a multi-set, as ``Index`` objects may contain repeated values).\n", + "Those views have some interesting consequences in the operations available on ``Index`` objects.\n", + "As a simple example, let's construct an ``Index`` from a list of integers:" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Int64Index([2, 3, 5, 7, 11], dtype='int64')" + ] + }, + "execution_count": 30, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "ind = pd.Index([2, 3, 5, 7, 11])\n", + "ind" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Index as immutable array\n", + "\n", + "The ``Index`` in many ways operates like an array.\n", + "For example, we can use standard Python indexing notation to retrieve values or slices:" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "3" + ] + }, + "execution_count": 31, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "ind[1]" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Int64Index([2, 5, 11], dtype='int64')" + ] + }, + "execution_count": 32, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "ind[::2]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "``Index`` objects also have many of the attributes familiar from NumPy arrays:" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "5 (5,) 1 int64\n" + ] + } + ], + "source": [ + "print(ind.size, ind.shape, ind.ndim, ind.dtype)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "One difference between ``Index`` objects and NumPy arrays is that indices are immutable–that is, they cannot be modified via the normal means:" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "ename": "TypeError", + "evalue": "Index does not support mutable operations", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mind\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;32m/Users/jakevdp/anaconda/lib/python3.5/site-packages/pandas/indexes/base.py\u001b[0m in \u001b[0;36m__setitem__\u001b[0;34m(self, key, value)\u001b[0m\n\u001b[1;32m 1243\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1244\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m__setitem__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mkey\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mvalue\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1245\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mTypeError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Index does not support mutable operations\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1246\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1247\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m__getitem__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mkey\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mTypeError\u001b[0m: Index does not support mutable operations" + ] + } + ], + "source": [ + "ind[1] = 0" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This immutability makes it safer to share indices between multiple ``DataFrame``s and arrays, without the potential for side effects from inadvertent index modification." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Index as ordered set\n", + "\n", + "Pandas objects are designed to facilitate operations such as joins across datasets, which depend on many aspects of set arithmetic.\n", + "The ``Index`` object follows many of the conventions used by Python's built-in ``set`` data structure, so that unions, intersections, differences, and other combinations can be computed in a familiar way:" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "indA = pd.Index([1, 3, 5, 7, 9])\n", + "indB = pd.Index([2, 3, 5, 7, 11])" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Int64Index([3, 5, 7], dtype='int64')" + ] + }, + "execution_count": 36, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "indA & indB # intersection" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Int64Index([1, 2, 3, 5, 7, 9, 11], dtype='int64')" + ] + }, + "execution_count": 37, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "indA | indB # union" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Int64Index([1, 2, 9, 11], dtype='int64')" + ] + }, + "execution_count": 38, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "indA ^ indB # symmetric difference" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "These operations may also be accessed via object methods, for example ``indA.intersection(indB)``." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "< [Data Manipulation with Pandas](03.00-Introduction-to-Pandas.ipynb) | [Contents](Index.ipynb) | [Data Indexing and Selection](03.02-Data-Indexing-and-Selection.ipynb) >" + ] + } + ], + "metadata": { + "anaconda-cloud": {}, + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.1" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/pandas/03.02-Data-Indexing-and-Selection.ipynb b/pandas/03.02-Data-Indexing-and-Selection.ipynb new file mode 100644 index 0000000..67326cb --- /dev/null +++ b/pandas/03.02-Data-Indexing-and-Selection.ipynb @@ -0,0 +1,1601 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "\n", + "*This notebook contains an excerpt from the [Python Data Science Handbook](http://shop.oreilly.com/product/0636920034919.do) by Jake VanderPlas; the content is available [on GitHub](https://github.com/jakevdp/PythonDataScienceHandbook).*\n", + "\n", + "*The text is released under the [CC-BY-NC-ND license](https://creativecommons.org/licenses/by-nc-nd/3.0/us/legalcode), and code is released under the [MIT license](https://opensource.org/licenses/MIT). If you find this content useful, please consider supporting the work by [buying the book](http://shop.oreilly.com/product/0636920034919.do)!*\n", + "\n", + "*No changes were made to the contents of this notebook from the original.*" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "< [Introducing Pandas Objects](03.01-Introducing-Pandas-Objects.ipynb) | [Contents](Index.ipynb) | [Operating on Data in Pandas](03.03-Operations-in-Pandas.ipynb) >" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Data Indexing and Selection" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In [Chapter 2](02.00-Introduction-to-NumPy.ipynb), we looked in detail at methods and tools to access, set, and modify values in NumPy arrays.\n", + "These included indexing (e.g., ``arr[2, 1]``), slicing (e.g., ``arr[:, 1:5]``), masking (e.g., ``arr[arr > 0]``), fancy indexing (e.g., ``arr[0, [1, 5]]``), and combinations thereof (e.g., ``arr[:, [1, 5]]``).\n", + "Here we'll look at similar means of accessing and modifying values in Pandas ``Series`` and ``DataFrame`` objects.\n", + "If you have used the NumPy patterns, the corresponding patterns in Pandas will feel very familiar, though there are a few quirks to be aware of.\n", + "\n", + "We'll start with the simple case of the one-dimensional ``Series`` object, and then move on to the more complicated two-dimesnional ``DataFrame`` object." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Data Selection in Series\n", + "\n", + "As we saw in the previous section, a ``Series`` object acts in many ways like a one-dimensional NumPy array, and in many ways like a standard Python dictionary.\n", + "If we keep these two overlapping analogies in mind, it will help us to understand the patterns of data indexing and selection in these arrays." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Series as dictionary\n", + "\n", + "Like a dictionary, the ``Series`` object provides a mapping from a collection of keys to a collection of values:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "a 0.25\n", + "b 0.50\n", + "c 0.75\n", + "d 1.00\n", + "dtype: float64" + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import pandas as pd\n", + "data = pd.Series([0.25, 0.5, 0.75, 1.0],\n", + " index=['a', 'b', 'c', 'd'])\n", + "data" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "0.5" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data['b']" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can also use dictionary-like Python expressions and methods to examine the keys/indices and values:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "'a' in data" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Index(['a', 'b', 'c', 'd'], dtype='object')" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data.keys()" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[('a', 0.25), ('b', 0.5), ('c', 0.75), ('d', 1.0)]" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "list(data.items())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "``Series`` objects can even be modified with a dictionary-like syntax.\n", + "Just as you can extend a dictionary by assigning to a new key, you can extend a ``Series`` by assigning to a new index value:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "a 0.25\n", + "b 0.50\n", + "c 0.75\n", + "d 1.00\n", + "e 1.25\n", + "dtype: float64" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data['e'] = 1.25\n", + "data" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This easy mutability of the objects is a convenient feature: under the hood, Pandas is making decisions about memory layout and data copying that might need to take place; the user generally does not need to worry about these issues." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Series as one-dimensional array" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "A ``Series`` builds on this dictionary-like interface and provides array-style item selection via the same basic mechanisms as NumPy arrays – that is, *slices*, *masking*, and *fancy indexing*.\n", + "Examples of these are as follows:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "a 0.25\n", + "b 0.50\n", + "c 0.75\n", + "dtype: float64" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# slicing by explicit index\n", + "data['a':'c']" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "a 0.25\n", + "b 0.50\n", + "dtype: float64" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# slicing by implicit integer index\n", + "data[0:2]" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "b 0.50\n", + "c 0.75\n", + "dtype: float64" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# masking\n", + "data[(data > 0.3) & (data < 0.8)]" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "a 0.25\n", + "e 1.25\n", + "dtype: float64" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# fancy indexing\n", + "data[['a', 'e']]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Among these, slicing may be the source of the most confusion.\n", + "Notice that when slicing with an explicit index (i.e., ``data['a':'c']``), the final index is *included* in the slice, while when slicing with an implicit index (i.e., ``data[0:2]``), the final index is *excluded* from the slice." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Indexers: loc, iloc, and ix\n", + "\n", + "These slicing and indexing conventions can be a source of confusion.\n", + "For example, if your ``Series`` has an explicit integer index, an indexing operation such as ``data[1]`` will use the explicit indices, while a slicing operation like ``data[1:3]`` will use the implicit Python-style index." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "1 a\n", + "3 b\n", + "5 c\n", + "dtype: object" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data = pd.Series(['a', 'b', 'c'], index=[1, 3, 5])\n", + "data" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'a'" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# explicit index when indexing\n", + "data[1]" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "3 b\n", + "5 c\n", + "dtype: object" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# implicit index when slicing\n", + "data[1:3]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Because of this potential confusion in the case of integer indexes, Pandas provides some special *indexer* attributes that explicitly expose certain indexing schemes.\n", + "These are not functional methods, but attributes that expose a particular slicing interface to the data in the ``Series``.\n", + "\n", + "First, the ``loc`` attribute allows indexing and slicing that always references the explicit index:" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'a'" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data.loc[1]" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "1 a\n", + "3 b\n", + "dtype: object" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data.loc[1:3]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The ``iloc`` attribute allows indexing and slicing that always references the implicit Python-style index:" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'b'" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data.iloc[1]" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "3 b\n", + "5 c\n", + "dtype: object" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data.iloc[1:3]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "A third indexing attribute, ``ix``, is a hybrid of the two, and for ``Series`` objects is equivalent to standard ``[]``-based indexing.\n", + "The purpose of the ``ix`` indexer will become more apparent in the context of ``DataFrame`` objects, which we will discuss in a moment.\n", + "\n", + "One guiding principle of Python code is that \"explicit is better than implicit.\"\n", + "The explicit nature of ``loc`` and ``iloc`` make them very useful in maintaining clean and readable code; especially in the case of integer indexes, I recommend using these both to make code easier to read and understand, and to prevent subtle bugs due to the mixed indexing/slicing convention." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Data Selection in DataFrame\n", + "\n", + "Recall that a ``DataFrame`` acts in many ways like a two-dimensional or structured array, and in other ways like a dictionary of ``Series`` structures sharing the same index.\n", + "These analogies can be helpful to keep in mind as we explore data selection within this structure." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### DataFrame as a dictionary\n", + "\n", + "The first analogy we will consider is the ``DataFrame`` as a dictionary of related ``Series`` objects.\n", + "Let's return to our example of areas and populations of states:" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
areapop
California42396738332521
Florida17031219552860
Illinois14999512882135
New York14129719651127
Texas69566226448193
\n", + "
" + ], + "text/plain": [ + " area pop\n", + "California 423967 38332521\n", + "Florida 170312 19552860\n", + "Illinois 149995 12882135\n", + "New York 141297 19651127\n", + "Texas 695662 26448193" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "area = pd.Series({'California': 423967, 'Texas': 695662,\n", + " 'New York': 141297, 'Florida': 170312,\n", + " 'Illinois': 149995})\n", + "pop = pd.Series({'California': 38332521, 'Texas': 26448193,\n", + " 'New York': 19651127, 'Florida': 19552860,\n", + " 'Illinois': 12882135})\n", + "data = pd.DataFrame({'area':area, 'pop':pop})\n", + "data" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The individual ``Series`` that make up the columns of the ``DataFrame`` can be accessed via dictionary-style indexing of the column name:" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "California 423967\n", + "Florida 170312\n", + "Illinois 149995\n", + "New York 141297\n", + "Texas 695662\n", + "Name: area, dtype: int64" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data['area']" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Equivalently, we can use attribute-style access with column names that are strings:" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "California 423967\n", + "Florida 170312\n", + "Illinois 149995\n", + "New York 141297\n", + "Texas 695662\n", + "Name: area, dtype: int64" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data.area" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This attribute-style column access actually accesses the exact same object as the dictionary-style access:" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data.area is data['area']" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Though this is a useful shorthand, keep in mind that it does not work for all cases!\n", + "For example, if the column names are not strings, or if the column names conflict with methods of the ``DataFrame``, this attribute-style access is not possible.\n", + "For example, the ``DataFrame`` has a ``pop()`` method, so ``data.pop`` will point to this rather than the ``\"pop\"`` column:" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "False" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data.pop is data['pop']" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In particular, you should avoid the temptation to try column assignment via attribute (i.e., use ``data['pop'] = z`` rather than ``data.pop = z``).\n", + "\n", + "Like with the ``Series`` objects discussed earlier, this dictionary-style syntax can also be used to modify the object, in this case adding a new column:" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
areapopdensity
California4239673833252190.413926
Florida17031219552860114.806121
Illinois1499951288213585.883763
New York14129719651127139.076746
Texas6956622644819338.018740
\n", + "
" + ], + "text/plain": [ + " area pop density\n", + "California 423967 38332521 90.413926\n", + "Florida 170312 19552860 114.806121\n", + "Illinois 149995 12882135 85.883763\n", + "New York 141297 19651127 139.076746\n", + "Texas 695662 26448193 38.018740" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data['density'] = data['pop'] / data['area']\n", + "data" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This shows a preview of the straightforward syntax of element-by-element arithmetic between ``Series`` objects; we'll dig into this further in [Operating on Data in Pandas](03.03-Operations-in-Pandas.ipynb)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### DataFrame as two-dimensional array\n", + "\n", + "As mentioned previously, we can also view the ``DataFrame`` as an enhanced two-dimensional array.\n", + "We can examine the raw underlying data array using the ``values`` attribute:" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[ 4.23967000e+05, 3.83325210e+07, 9.04139261e+01],\n", + " [ 1.70312000e+05, 1.95528600e+07, 1.14806121e+02],\n", + " [ 1.49995000e+05, 1.28821350e+07, 8.58837628e+01],\n", + " [ 1.41297000e+05, 1.96511270e+07, 1.39076746e+02],\n", + " [ 6.95662000e+05, 2.64481930e+07, 3.80187404e+01]])" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data.values" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "With this picture in mind, many familiar array-like observations can be done on the ``DataFrame`` itself.\n", + "For example, we can transpose the full ``DataFrame`` to swap rows and columns:" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
CaliforniaFloridaIllinoisNew YorkTexas
area4.239670e+051.703120e+051.499950e+051.412970e+056.956620e+05
pop3.833252e+071.955286e+071.288214e+071.965113e+072.644819e+07
density9.041393e+011.148061e+028.588376e+011.390767e+023.801874e+01
\n", + "
" + ], + "text/plain": [ + " California Florida Illinois New York Texas\n", + "area 4.239670e+05 1.703120e+05 1.499950e+05 1.412970e+05 6.956620e+05\n", + "pop 3.833252e+07 1.955286e+07 1.288214e+07 1.965113e+07 2.644819e+07\n", + "density 9.041393e+01 1.148061e+02 8.588376e+01 1.390767e+02 3.801874e+01" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data.T" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "When it comes to indexing of ``DataFrame`` objects, however, it is clear that the dictionary-style indexing of columns precludes our ability to simply treat it as a NumPy array.\n", + "In particular, passing a single index to an array accesses a row:" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([ 4.23967000e+05, 3.83325210e+07, 9.04139261e+01])" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data.values[0]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "and passing a single \"index\" to a ``DataFrame`` accesses a column:" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "California 423967\n", + "Florida 170312\n", + "Illinois 149995\n", + "New York 141297\n", + "Texas 695662\n", + "Name: area, dtype: int64" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data['area']" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "Thus for array-style indexing, we need another convention.\n", + "Here Pandas again uses the ``loc``, ``iloc``, and ``ix`` indexers mentioned earlier.\n", + "Using the ``iloc`` indexer, we can index the underlying array as if it is a simple NumPy array (using the implicit Python-style index), but the ``DataFrame`` index and column labels are maintained in the result:" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
areapop
California42396738332521
Florida17031219552860
Illinois14999512882135
\n", + "
" + ], + "text/plain": [ + " area pop\n", + "California 423967 38332521\n", + "Florida 170312 19552860\n", + "Illinois 149995 12882135" + ] + }, + "execution_count": 28, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data.iloc[:3, :2]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Similarly, using the ``loc`` indexer we can index the underlying data in an array-like style but using the explicit index and column names:" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
areapop
California42396738332521
Florida17031219552860
Illinois14999512882135
\n", + "
" + ], + "text/plain": [ + " area pop\n", + "California 423967 38332521\n", + "Florida 170312 19552860\n", + "Illinois 149995 12882135" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data.loc[:'Illinois', :'pop']" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "The ``ix`` indexer allows a hybrid of these two approaches:" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
areapop
California42396738332521
Florida17031219552860
Illinois14999512882135
\n", + "
" + ], + "text/plain": [ + " area pop\n", + "California 423967 38332521\n", + "Florida 170312 19552860\n", + "Illinois 149995 12882135" + ] + }, + "execution_count": 30, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data.ix[:3, :'pop']" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Keep in mind that for integer indices, the ``ix`` indexer is subject to the same potential sources of confusion as discussed for integer-indexed ``Series`` objects.\n", + "\n", + "Any of the familiar NumPy-style data access patterns can be used within these indexers.\n", + "For example, in the ``loc`` indexer we can combine masking and fancy indexing as in the following:" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
popdensity
Florida19552860114.806121
New York19651127139.076746
\n", + "
" + ], + "text/plain": [ + " pop density\n", + "Florida 19552860 114.806121\n", + "New York 19651127 139.076746" + ] + }, + "execution_count": 31, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data.loc[data.density > 100, ['pop', 'density']]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Any of these indexing conventions may also be used to set or modify values; this is done in the standard way that you might be accustomed to from working with NumPy:" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
areapopdensity
California4239673833252190.000000
Florida17031219552860114.806121
Illinois1499951288213585.883763
New York14129719651127139.076746
Texas6956622644819338.018740
\n", + "
" + ], + "text/plain": [ + " area pop density\n", + "California 423967 38332521 90.000000\n", + "Florida 170312 19552860 114.806121\n", + "Illinois 149995 12882135 85.883763\n", + "New York 141297 19651127 139.076746\n", + "Texas 695662 26448193 38.018740" + ] + }, + "execution_count": 32, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data.iloc[0, 2] = 90\n", + "data" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To build up your fluency in Pandas data manipulation, I suggest spending some time with a simple ``DataFrame`` and exploring the types of indexing, slicing, masking, and fancy indexing that are allowed by these various indexing approaches." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Additional indexing conventions\n", + "\n", + "There are a couple extra indexing conventions that might seem at odds with the preceding discussion, but nevertheless can be very useful in practice.\n", + "First, while *indexing* refers to columns, *slicing* refers to rows:" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
areapopdensity
Florida17031219552860114.806121
Illinois1499951288213585.883763
\n", + "
" + ], + "text/plain": [ + " area pop density\n", + "Florida 170312 19552860 114.806121\n", + "Illinois 149995 12882135 85.883763" + ] + }, + "execution_count": 33, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data['Florida':'Illinois']" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Such slices can also refer to rows by number rather than by index:" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
areapopdensity
Florida17031219552860114.806121
Illinois1499951288213585.883763
\n", + "
" + ], + "text/plain": [ + " area pop density\n", + "Florida 170312 19552860 114.806121\n", + "Illinois 149995 12882135 85.883763" + ] + }, + "execution_count": 34, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data[1:3]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Similarly, direct masking operations are also interpreted row-wise rather than column-wise:" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
areapopdensity
Florida17031219552860114.806121
New York14129719651127139.076746
\n", + "
" + ], + "text/plain": [ + " area pop density\n", + "Florida 170312 19552860 114.806121\n", + "New York 141297 19651127 139.076746" + ] + }, + "execution_count": 35, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data[data.density > 100]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "These two conventions are syntactically similar to those on a NumPy array, and while these may not precisely fit the mold of the Pandas conventions, they are nevertheless quite useful in practice." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "< [Introducing Pandas Objects](03.01-Introducing-Pandas-Objects.ipynb) | [Contents](Index.ipynb) | [Operating on Data in Pandas](03.03-Operations-in-Pandas.ipynb) >" + ] + } + ], + "metadata": { + "anaconda-cloud": {}, + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.4.3" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/pandas/03.03-Operations-in-Pandas.ipynb b/pandas/03.03-Operations-in-Pandas.ipynb new file mode 100644 index 0000000..a601820 --- /dev/null +++ b/pandas/03.03-Operations-in-Pandas.ipynb @@ -0,0 +1,1035 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "\n", + "*This notebook contains an excerpt from the [Python Data Science Handbook](http://shop.oreilly.com/product/0636920034919.do) by Jake VanderPlas; the content is available [on GitHub](https://github.com/jakevdp/PythonDataScienceHandbook).*\n", + "\n", + "*The text is released under the [CC-BY-NC-ND license](https://creativecommons.org/licenses/by-nc-nd/3.0/us/legalcode), and code is released under the [MIT license](https://opensource.org/licenses/MIT). If you find this content useful, please consider supporting the work by [buying the book](http://shop.oreilly.com/product/0636920034919.do)!*\n", + "\n", + "*No changes were made to the contents of this notebook from the original.*" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "< [Data Indexing and Selection](03.02-Data-Indexing-and-Selection.ipynb) | [Contents](Index.ipynb) | [Handling Missing Data](03.04-Missing-Values.ipynb) >" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Operating on Data in Pandas" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "One of the essential pieces of NumPy is the ability to perform quick element-wise operations, both with basic arithmetic (addition, subtraction, multiplication, etc.) and with more sophisticated operations (trigonometric functions, exponential and logarithmic functions, etc.).\n", + "Pandas inherits much of this functionality from NumPy, and the ufuncs that we introduced in [Computation on NumPy Arrays: Universal Functions](02.03-Computation-on-arrays-ufuncs.ipynb) are key to this.\n", + "\n", + "Pandas includes a couple useful twists, however: for unary operations like negation and trigonometric functions, these ufuncs will *preserve index and column labels* in the output, and for binary operations such as addition and multiplication, Pandas will automatically *align indices* when passing the objects to the ufunc.\n", + "This means that keeping the context of data and combining data from different sources–both potentially error-prone tasks with raw NumPy arrays–become essentially foolproof ones with Pandas.\n", + "We will additionally see that there are well-defined operations between one-dimensional ``Series`` structures and two-dimensional ``DataFrame`` structures." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Ufuncs: Index Preservation\n", + "\n", + "Because Pandas is designed to work with NumPy, any NumPy ufunc will work on Pandas ``Series`` and ``DataFrame`` objects.\n", + "Let's start by defining a simple ``Series`` and ``DataFrame`` on which to demonstrate this:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import pandas as pd\n", + "import numpy as np" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "0 6\n", + "1 3\n", + "2 7\n", + "3 4\n", + "dtype: int64" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "rng = np.random.RandomState(42)\n", + "ser = pd.Series(rng.randint(0, 10, 4))\n", + "ser" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ABCD
06926
17437
27254
\n", + "
" + ], + "text/plain": [ + " A B C D\n", + "0 6 9 2 6\n", + "1 7 4 3 7\n", + "2 7 2 5 4" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df = pd.DataFrame(rng.randint(0, 10, (3, 4)),\n", + " columns=['A', 'B', 'C', 'D'])\n", + "df" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If we apply a NumPy ufunc on either of these objects, the result will be another Pandas object *with the indices preserved:*" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "0 403.428793\n", + "1 20.085537\n", + "2 1096.633158\n", + "3 54.598150\n", + "dtype: float64" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.exp(ser)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Or, for a slightly more complex calculation:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ABCD
0-1.0000007.071068e-011.000000-1.000000e+00
1-0.7071071.224647e-160.707107-7.071068e-01
2-0.7071071.000000e+00-0.7071071.224647e-16
\n", + "
" + ], + "text/plain": [ + " A B C D\n", + "0 -1.000000 7.071068e-01 1.000000 -1.000000e+00\n", + "1 -0.707107 1.224647e-16 0.707107 -7.071068e-01\n", + "2 -0.707107 1.000000e+00 -0.707107 1.224647e-16" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.sin(df * np.pi / 4)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Any of the ufuncs discussed in [Computation on NumPy Arrays: Universal Functions](02.03-Computation-on-arrays-ufuncs.ipynb) can be used in a similar manner." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## UFuncs: Index Alignment\n", + "\n", + "For binary operations on two ``Series`` or ``DataFrame`` objects, Pandas will align indices in the process of performing the operation.\n", + "This is very convenient when working with incomplete data, as we'll see in some of the examples that follow." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Index alignment in Series\n", + "\n", + "As an example, suppose we are combining two different data sources, and find only the top three US states by *area* and the top three US states by *population*:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "area = pd.Series({'Alaska': 1723337, 'Texas': 695662,\n", + " 'California': 423967}, name='area')\n", + "population = pd.Series({'California': 38332521, 'Texas': 26448193,\n", + " 'New York': 19651127}, name='population')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's see what happens when we divide these to compute the population density:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Alaska NaN\n", + "California 90.413926\n", + "New York NaN\n", + "Texas 38.018740\n", + "dtype: float64" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "population / area" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The resulting array contains the *union* of indices of the two input arrays, which could be determined using standard Python set arithmetic on these indices:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Index(['Alaska', 'California', 'New York', 'Texas'], dtype='object')" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "area.index | population.index" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Any item for which one or the other does not have an entry is marked with ``NaN``, or \"Not a Number,\" which is how Pandas marks missing data (see further discussion of missing data in [Handling Missing Data](03.04-Missing-Values.ipynb)).\n", + "This index matching is implemented this way for any of Python's built-in arithmetic expressions; any missing values are filled in with NaN by default:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "0 NaN\n", + "1 5.0\n", + "2 9.0\n", + "3 NaN\n", + "dtype: float64" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "A = pd.Series([2, 4, 6], index=[0, 1, 2])\n", + "B = pd.Series([1, 3, 5], index=[1, 2, 3])\n", + "A + B" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If using NaN values is not the desired behavior, the fill value can be modified using appropriate object methods in place of the operators.\n", + "For example, calling ``A.add(B)`` is equivalent to calling ``A + B``, but allows optional explicit specification of the fill value for any elements in ``A`` or ``B`` that might be missing:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "0 2.0\n", + "1 5.0\n", + "2 9.0\n", + "3 5.0\n", + "dtype: float64" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "A.add(B, fill_value=0)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Index alignment in DataFrame\n", + "\n", + "A similar type of alignment takes place for *both* columns and indices when performing operations on ``DataFrame``s:" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
AB
0111
151
\n", + "
" + ], + "text/plain": [ + " A B\n", + "0 1 11\n", + "1 5 1" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "A = pd.DataFrame(rng.randint(0, 20, (2, 2)),\n", + " columns=list('AB'))\n", + "A" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
BAC
0409
1580
2926
\n", + "
" + ], + "text/plain": [ + " B A C\n", + "0 4 0 9\n", + "1 5 8 0\n", + "2 9 2 6" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "B = pd.DataFrame(rng.randint(0, 10, (3, 3)),\n", + " columns=list('BAC'))\n", + "B" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ABC
01.015.0NaN
113.06.0NaN
2NaNNaNNaN
\n", + "
" + ], + "text/plain": [ + " A B C\n", + "0 1.0 15.0 NaN\n", + "1 13.0 6.0 NaN\n", + "2 NaN NaN NaN" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "A + B" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Notice that indices are aligned correctly irrespective of their order in the two objects, and indices in the result are sorted.\n", + "As was the case with ``Series``, we can use the associated object's arithmetic method and pass any desired ``fill_value`` to be used in place of missing entries.\n", + "Here we'll fill with the mean of all values in ``A`` (computed by first stacking the rows of ``A``):" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ABC
01.015.013.5
113.06.04.5
26.513.510.5
\n", + "
" + ], + "text/plain": [ + " A B C\n", + "0 1.0 15.0 13.5\n", + "1 13.0 6.0 4.5\n", + "2 6.5 13.5 10.5" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "fill = A.stack().mean()\n", + "A.add(B, fill_value=fill)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The following table lists Python operators and their equivalent Pandas object methods:\n", + "\n", + "| Python Operator | Pandas Method(s) |\n", + "|-----------------|---------------------------------------|\n", + "| ``+`` | ``add()`` |\n", + "| ``-`` | ``sub()``, ``subtract()`` |\n", + "| ``*`` | ``mul()``, ``multiply()`` |\n", + "| ``/`` | ``truediv()``, ``div()``, ``divide()``|\n", + "| ``//`` | ``floordiv()`` |\n", + "| ``%`` | ``mod()`` |\n", + "| ``**`` | ``pow()`` |\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Ufuncs: Operations Between DataFrame and Series\n", + "\n", + "When performing operations between a ``DataFrame`` and a ``Series``, the index and column alignment is similarly maintained.\n", + "Operations between a ``DataFrame`` and a ``Series`` are similar to operations between a two-dimensional and one-dimensional NumPy array.\n", + "Consider one common operation, where we find the difference of a two-dimensional array and one of its rows:" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[3, 8, 2, 4],\n", + " [2, 6, 4, 8],\n", + " [6, 1, 3, 8]])" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "A = rng.randint(10, size=(3, 4))\n", + "A" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[ 0, 0, 0, 0],\n", + " [-1, -2, 2, 4],\n", + " [ 3, -7, 1, 4]])" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "A - A[0]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "According to NumPy's broadcasting rules (see [Computation on Arrays: Broadcasting](02.05-Computation-on-arrays-broadcasting.ipynb)), subtraction between a two-dimensional array and one of its rows is applied row-wise.\n", + "\n", + "In Pandas, the convention similarly operates row-wise by default:" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
QRST
00000
1-1-224
23-714
\n", + "
" + ], + "text/plain": [ + " Q R S T\n", + "0 0 0 0 0\n", + "1 -1 -2 2 4\n", + "2 3 -7 1 4" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df = pd.DataFrame(A, columns=list('QRST'))\n", + "df - df.iloc[0]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If you would instead like to operate column-wise, you can use the object methods mentioned earlier, while specifying the ``axis`` keyword:" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
QRST
0-50-6-4
1-40-22
25027
\n", + "
" + ], + "text/plain": [ + " Q R S T\n", + "0 -5 0 -6 -4\n", + "1 -4 0 -2 2\n", + "2 5 0 2 7" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.subtract(df['R'], axis=0)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Note that these ``DataFrame``/``Series`` operations, like the operations discussed above, will automatically align indices between the two elements:" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Q 3\n", + "S 2\n", + "Name: 0, dtype: int64" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "halfrow = df.iloc[0, ::2]\n", + "halfrow" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
QRST
00.0NaN0.0NaN
1-1.0NaN2.0NaN
23.0NaN1.0NaN
\n", + "
" + ], + "text/plain": [ + " Q R S T\n", + "0 0.0 NaN 0.0 NaN\n", + "1 -1.0 NaN 2.0 NaN\n", + "2 3.0 NaN 1.0 NaN" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df - halfrow" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This preservation and alignment of indices and columns means that operations on data in Pandas will always maintain the data context, which prevents the types of silly errors that might come up when working with heterogeneous and/or misaligned data in raw NumPy arrays." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "< [Data Indexing and Selection](03.02-Data-Indexing-and-Selection.ipynb) | [Contents](Index.ipynb) | [Handling Missing Data](03.04-Missing-Values.ipynb) >" + ] + } + ], + "metadata": { + "anaconda-cloud": {}, + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.4.3" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/pandas/03.04-Missing-Values.ipynb b/pandas/03.04-Missing-Values.ipynb new file mode 100644 index 0000000..4febcb5 --- /dev/null +++ b/pandas/03.04-Missing-Values.ipynb @@ -0,0 +1,1296 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "\n", + "*This notebook contains an excerpt from the [Python Data Science Handbook](http://shop.oreilly.com/product/0636920034919.do) by Jake VanderPlas; the content is available [on GitHub](https://github.com/jakevdp/PythonDataScienceHandbook).*\n", + "\n", + "*The text is released under the [CC-BY-NC-ND license](https://creativecommons.org/licenses/by-nc-nd/3.0/us/legalcode), and code is released under the [MIT license](https://opensource.org/licenses/MIT). If you find this content useful, please consider supporting the work by [buying the book](http://shop.oreilly.com/product/0636920034919.do)!*\n", + "\n", + "*No changes were made to the contents of this notebook from the original.*" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "< [Operating on Data in Pandas](03.03-Operations-in-Pandas.ipynb) | [Contents](Index.ipynb) | [Hierarchical Indexing](03.05-Hierarchical-Indexing.ipynb) >" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Handling Missing Data" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The difference between data found in many tutorials and data in the real world is that real-world data is rarely clean and homogeneous.\n", + "In particular, many interesting datasets will have some amount of data missing.\n", + "To make matters even more complicated, different data sources may indicate missing data in different ways.\n", + "\n", + "In this section, we will discuss some general considerations for missing data, discuss how Pandas chooses to represent it, and demonstrate some built-in Pandas tools for handling missing data in Python.\n", + "Here and throughout the book, we'll refer to missing data in general as *null*, *NaN*, or *NA* values." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Trade-Offs in Missing Data Conventions\n", + "\n", + "There are a number of schemes that have been developed to indicate the presence of missing data in a table or DataFrame.\n", + "Generally, they revolve around one of two strategies: using a *mask* that globally indicates missing values, or choosing a *sentinel value* that indicates a missing entry.\n", + "\n", + "In the masking approach, the mask might be an entirely separate Boolean array, or it may involve appropriation of one bit in the data representation to locally indicate the null status of a value.\n", + "\n", + "In the sentinel approach, the sentinel value could be some data-specific convention, such as indicating a missing integer value with -9999 or some rare bit pattern, or it could be a more global convention, such as indicating a missing floating-point value with NaN (Not a Number), a special value which is part of the IEEE floating-point specification.\n", + "\n", + "None of these approaches is without trade-offs: use of a separate mask array requires allocation of an additional Boolean array, which adds overhead in both storage and computation. A sentinel value reduces the range of valid values that can be represented, and may require extra (often non-optimized) logic in CPU and GPU arithmetic. Common special values like NaN are not available for all data types.\n", + "\n", + "As in most cases where no universally optimal choice exists, different languages and systems use different conventions.\n", + "For example, the R language uses reserved bit patterns within each data type as sentinel values indicating missing data, while the SciDB system uses an extra byte attached to every cell which indicates a NA state." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Missing Data in Pandas\n", + "\n", + "The way in which Pandas handles missing values is constrained by its reliance on the NumPy package, which does not have a built-in notion of NA values for non-floating-point data types.\n", + "\n", + "Pandas could have followed R's lead in specifying bit patterns for each individual data type to indicate nullness, but this approach turns out to be rather unwieldy.\n", + "While R contains four basic data types, NumPy supports *far* more than this: for example, while R has a single integer type, NumPy supports *fourteen* basic integer types once you account for available precisions, signedness, and endianness of the encoding.\n", + "Reserving a specific bit pattern in all available NumPy types would lead to an unwieldy amount of overhead in special-casing various operations for various types, likely even requiring a new fork of the NumPy package. Further, for the smaller data types (such as 8-bit integers), sacrificing a bit to use as a mask will significantly reduce the range of values it can represent.\n", + "\n", + "NumPy does have support for masked arrays – that is, arrays that have a separate Boolean mask array attached for marking data as \"good\" or \"bad.\"\n", + "Pandas could have derived from this, but the overhead in both storage, computation, and code maintenance makes that an unattractive choice.\n", + "\n", + "With these constraints in mind, Pandas chose to use sentinels for missing data, and further chose to use two already-existing Python null values: the special floating-point ``NaN`` value, and the Python ``None`` object.\n", + "This choice has some side effects, as we will see, but in practice ends up being a good compromise in most cases of interest." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### ``None``: Pythonic missing data\n", + "\n", + "The first sentinel value used by Pandas is ``None``, a Python singleton object that is often used for missing data in Python code.\n", + "Because it is a Python object, ``None`` cannot be used in any arbitrary NumPy/Pandas array, but only in arrays with data type ``'object'`` (i.e., arrays of Python objects):" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import pandas as pd" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([1, None, 3, 4], dtype=object)" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "vals1 = np.array([1, None, 3, 4])\n", + "vals1" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This ``dtype=object`` means that the best common type representation NumPy could infer for the contents of the array is that they are Python objects.\n", + "While this kind of object array is useful for some purposes, any operations on the data will be done at the Python level, with much more overhead than the typically fast operations seen for arrays with native types:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "dtype = object\n", + "10 loops, best of 3: 78.2 ms per loop\n", + "\n", + "dtype = int\n", + "100 loops, best of 3: 3.06 ms per loop\n", + "\n" + ] + } + ], + "source": [ + "for dtype in ['object', 'int']:\n", + " print(\"dtype =\", dtype)\n", + " %timeit np.arange(1E6, dtype=dtype).sum()\n", + " print()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The use of Python objects in an array also means that if you perform aggregations like ``sum()`` or ``min()`` across an array with a ``None`` value, you will generally get an error:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "ename": "TypeError", + "evalue": "unsupported operand type(s) for +: 'int' and 'NoneType'", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mvals1\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msum\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;32m/Users/jakevdp/anaconda/lib/python3.5/site-packages/numpy/core/_methods.py\u001b[0m in \u001b[0;36m_sum\u001b[0;34m(a, axis, dtype, out, keepdims)\u001b[0m\n\u001b[1;32m 30\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 31\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m_sum\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0maxis\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mNone\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdtype\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mNone\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mout\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mNone\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mkeepdims\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mFalse\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 32\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mumr_sum\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0maxis\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdtype\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mout\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mkeepdims\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 33\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 34\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m_prod\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0maxis\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mNone\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdtype\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mNone\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mout\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mNone\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mkeepdims\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mFalse\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mTypeError\u001b[0m: unsupported operand type(s) for +: 'int' and 'NoneType'" + ] + } + ], + "source": [ + "vals1.sum()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This reflects the fact that addition between an integer and ``None`` is undefined." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### ``NaN``: Missing numerical data\n", + "\n", + "The other missing data representation, ``NaN`` (acronym for *Not a Number*), is different; it is a special floating-point value recognized by all systems that use the standard IEEE floating-point representation:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "dtype('float64')" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "vals2 = np.array([1, np.nan, 3, 4]) \n", + "vals2.dtype" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Notice that NumPy chose a native floating-point type for this array: this means that unlike the object array from before, this array supports fast operations pushed into compiled code.\n", + "You should be aware that ``NaN`` is a bit like a data virus–it infects any other object it touches.\n", + "Regardless of the operation, the result of arithmetic with ``NaN`` will be another ``NaN``:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "nan" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "1 + np.nan" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "nan" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "0 * np.nan" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Note that this means that aggregates over the values are well defined (i.e., they don't result in an error) but not always useful:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(nan, nan, nan)" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "vals2.sum(), vals2.min(), vals2.max()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "NumPy does provide some special aggregations that will ignore these missing values:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(8.0, 1.0, 4.0)" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.nansum(vals2), np.nanmin(vals2), np.nanmax(vals2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Keep in mind that ``NaN`` is specifically a floating-point value; there is no equivalent NaN value for integers, strings, or other types." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### NaN and None in Pandas\n", + "\n", + "``NaN`` and ``None`` both have their place, and Pandas is built to handle the two of them nearly interchangeably, converting between them where appropriate:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "0 1.0\n", + "1 NaN\n", + "2 2.0\n", + "3 NaN\n", + "dtype: float64" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pd.Series([1, np.nan, 2, None])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For types that don't have an available sentinel value, Pandas automatically type-casts when NA values are present.\n", + "For example, if we set a value in an integer array to ``np.nan``, it will automatically be upcast to a floating-point type to accommodate the NA:" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "0 0\n", + "1 1\n", + "dtype: int64" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "x = pd.Series(range(2), dtype=int)\n", + "x" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "0 NaN\n", + "1 1.0\n", + "dtype: float64" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "x[0] = None\n", + "x" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Notice that in addition to casting the integer array to floating point, Pandas automatically converts the ``None`` to a ``NaN`` value.\n", + "(Be aware that there is a proposal to add a native integer NA to Pandas in the future; as of this writing, it has not been included).\n", + "\n", + "While this type of magic may feel a bit hackish compared to the more unified approach to NA values in domain-specific languages like R, the Pandas sentinel/casting approach works quite well in practice and in my experience only rarely causes issues.\n", + "\n", + "The following table lists the upcasting conventions in Pandas when NA values are introduced:\n", + "\n", + "|Typeclass | Conversion When Storing NAs | NA Sentinel Value |\n", + "|--------------|-----------------------------|------------------------|\n", + "| ``floating`` | No change | ``np.nan`` |\n", + "| ``object`` | No change | ``None`` or ``np.nan`` |\n", + "| ``integer`` | Cast to ``float64`` | ``np.nan`` |\n", + "| ``boolean`` | Cast to ``object`` | ``None`` or ``np.nan`` |\n", + "\n", + "Keep in mind that in Pandas, string data is always stored with an ``object`` dtype." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Operating on Null Values\n", + "\n", + "As we have seen, Pandas treats ``None`` and ``NaN`` as essentially interchangeable for indicating missing or null values.\n", + "To facilitate this convention, there are several useful methods for detecting, removing, and replacing null values in Pandas data structures.\n", + "They are:\n", + "\n", + "- ``isnull()``: Generate a boolean mask indicating missing values\n", + "- ``notnull()``: Opposite of ``isnull()``\n", + "- ``dropna()``: Return a filtered version of the data\n", + "- ``fillna()``: Return a copy of the data with missing values filled or imputed\n", + "\n", + "We will conclude this section with a brief exploration and demonstration of these routines." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Detecting null values\n", + "Pandas data structures have two useful methods for detecting null data: ``isnull()`` and ``notnull()``.\n", + "Either one will return a Boolean mask over the data. For example:" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "data = pd.Series([1, np.nan, 'hello', None])" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "0 False\n", + "1 True\n", + "2 False\n", + "3 True\n", + "dtype: bool" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data.isnull()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "As mentioned in [Data Indexing and Selection](03.02-Data-Indexing-and-Selection.ipynb), Boolean masks can be used directly as a ``Series`` or ``DataFrame`` index:" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "0 1\n", + "2 hello\n", + "dtype: object" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data[data.notnull()]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The ``isnull()`` and ``notnull()`` methods produce similar Boolean results for ``DataFrame``s." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Dropping null values\n", + "\n", + "In addition to the masking used before, there are the convenience methods, ``dropna()``\n", + "(which removes NA values) and ``fillna()`` (which fills in NA values). For a ``Series``,\n", + "the result is straightforward:" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "0 1\n", + "2 hello\n", + "dtype: object" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data.dropna()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For a ``DataFrame``, there are more options.\n", + "Consider the following ``DataFrame``:" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
012
01.0NaN2
12.03.05
2NaN4.06
\n", + "
" + ], + "text/plain": [ + " 0 1 2\n", + "0 1.0 NaN 2\n", + "1 2.0 3.0 5\n", + "2 NaN 4.0 6" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df = pd.DataFrame([[1, np.nan, 2],\n", + " [2, 3, 5],\n", + " [np.nan, 4, 6]])\n", + "df" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We cannot drop single values from a ``DataFrame``; we can only drop full rows or full columns.\n", + "Depending on the application, you might want one or the other, so ``dropna()`` gives a number of options for a ``DataFrame``.\n", + "\n", + "By default, ``dropna()`` will drop all rows in which *any* null value is present:" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
012
12.03.05
\n", + "
" + ], + "text/plain": [ + " 0 1 2\n", + "1 2.0 3.0 5" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.dropna()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Alternatively, you can drop NA values along a different axis; ``axis=1`` drops all columns containing a null value:" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
2
02
15
26
\n", + "
" + ], + "text/plain": [ + " 2\n", + "0 2\n", + "1 5\n", + "2 6" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.dropna(axis='columns')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "But this drops some good data as well; you might rather be interested in dropping rows or columns with *all* NA values, or a majority of NA values.\n", + "This can be specified through the ``how`` or ``thresh`` parameters, which allow fine control of the number of nulls to allow through.\n", + "\n", + "The default is ``how='any'``, such that any row or column (depending on the ``axis`` keyword) containing a null value will be dropped.\n", + "You can also specify ``how='all'``, which will only drop rows/columns that are *all* null values:" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
0123
01.0NaN2NaN
12.03.05NaN
2NaN4.06NaN
\n", + "
" + ], + "text/plain": [ + " 0 1 2 3\n", + "0 1.0 NaN 2 NaN\n", + "1 2.0 3.0 5 NaN\n", + "2 NaN 4.0 6 NaN" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df[3] = np.nan\n", + "df" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
012
01.0NaN2
12.03.05
2NaN4.06
\n", + "
" + ], + "text/plain": [ + " 0 1 2\n", + "0 1.0 NaN 2\n", + "1 2.0 3.0 5\n", + "2 NaN 4.0 6" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.dropna(axis='columns', how='all')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For finer-grained control, the ``thresh`` parameter lets you specify a minimum number of non-null values for the row/column to be kept:" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
0123
12.03.05NaN
\n", + "
" + ], + "text/plain": [ + " 0 1 2 3\n", + "1 2.0 3.0 5 NaN" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.dropna(axis='rows', thresh=3)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here the first and last row have been dropped, because they contain only two non-null values." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Filling null values\n", + "\n", + "Sometimes rather than dropping NA values, you'd rather replace them with a valid value.\n", + "This value might be a single number like zero, or it might be some sort of imputation or interpolation from the good values.\n", + "You could do this in-place using the ``isnull()`` method as a mask, but because it is such a common operation Pandas provides the ``fillna()`` method, which returns a copy of the array with the null values replaced.\n", + "\n", + "Consider the following ``Series``:" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "a 1.0\n", + "b NaN\n", + "c 2.0\n", + "d NaN\n", + "e 3.0\n", + "dtype: float64" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data = pd.Series([1, np.nan, 2, None, 3], index=list('abcde'))\n", + "data" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can fill NA entries with a single value, such as zero:" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "a 1.0\n", + "b 0.0\n", + "c 2.0\n", + "d 0.0\n", + "e 3.0\n", + "dtype: float64" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data.fillna(0)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can specify a forward-fill to propagate the previous value forward:" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "a 1.0\n", + "b 1.0\n", + "c 2.0\n", + "d 2.0\n", + "e 3.0\n", + "dtype: float64" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# forward-fill\n", + "data.fillna(method='ffill')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Or we can specify a back-fill to propagate the next values backward:" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "a 1.0\n", + "b 2.0\n", + "c 2.0\n", + "d 3.0\n", + "e 3.0\n", + "dtype: float64" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# back-fill\n", + "data.fillna(method='bfill')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "For ``DataFrame``s, the options are similar, but we can also specify an ``axis`` along which the fills take place:" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
0123
01.0NaN2NaN
12.03.05NaN
2NaN4.06NaN
\n", + "
" + ], + "text/plain": [ + " 0 1 2 3\n", + "0 1.0 NaN 2 NaN\n", + "1 2.0 3.0 5 NaN\n", + "2 NaN 4.0 6 NaN" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
0123
01.01.02.02.0
12.03.05.05.0
2NaN4.06.06.0
\n", + "
" + ], + "text/plain": [ + " 0 1 2 3\n", + "0 1.0 1.0 2.0 2.0\n", + "1 2.0 3.0 5.0 5.0\n", + "2 NaN 4.0 6.0 6.0" + ] + }, + "execution_count": 28, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.fillna(method='ffill', axis=1)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Notice that if a previous value is not available during a forward fill, the NA value remains." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "< [Operating on Data in Pandas](03.03-Operations-in-Pandas.ipynb) | [Contents](Index.ipynb) | [Hierarchical Indexing](03.05-Hierarchical-Indexing.ipynb) >" + ] + } + ], + "metadata": { + "anaconda-cloud": {}, + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.4.3" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/pandas/03.05-Hierarchical-Indexing.ipynb b/pandas/03.05-Hierarchical-Indexing.ipynb new file mode 100644 index 0000000..9fc5898 --- /dev/null +++ b/pandas/03.05-Hierarchical-Indexing.ipynb @@ -0,0 +1,2520 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "\n", + "*This notebook contains an excerpt from the [Python Data Science Handbook](http://shop.oreilly.com/product/0636920034919.do) by Jake VanderPlas; the content is available [on GitHub](https://github.com/jakevdp/PythonDataScienceHandbook).*\n", + "\n", + "*The text is released under the [CC-BY-NC-ND license](https://creativecommons.org/licenses/by-nc-nd/3.0/us/legalcode), and code is released under the [MIT license](https://opensource.org/licenses/MIT). If you find this content useful, please consider supporting the work by [buying the book](http://shop.oreilly.com/product/0636920034919.do)!*\n", + "\n", + "*No changes were made to the contents of this notebook from the original.*" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "< [Handling Missing Data](03.04-Missing-Values.ipynb) | [Contents](Index.ipynb) | [Combining Datasets: Concat and Append](03.06-Concat-And-Append.ipynb) >" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Hierarchical Indexing\n", + "\n", + "Up to this point we've been focused primarily on one-dimensional and two-dimensional data, stored in Pandas ``Series`` and ``DataFrame`` objects, respectively.\n", + "Often it is useful to go beyond this and store higher-dimensional data–that is, data indexed by more than one or two keys.\n", + "While Pandas does provide ``Panel`` and ``Panel4D`` objects that natively handle three-dimensional and four-dimensional data (see [Aside: Panel Data](#Aside:-Panel-Data)), a far more common pattern in practice is to make use of *hierarchical indexing* (also known as *multi-indexing*) to incorporate multiple index *levels* within a single index.\n", + "In this way, higher-dimensional data can be compactly represented within the familiar one-dimensional ``Series`` and two-dimensional ``DataFrame`` objects.\n", + "\n", + "In this section, we'll explore the direct creation of ``MultiIndex`` objects, considerations when indexing, slicing, and computing statistics across multiply indexed data, and useful routines for converting between simple and hierarchically indexed representations of your data.\n", + "\n", + "We begin with the standard imports:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import pandas as pd\n", + "import numpy as np" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## A Multiply Indexed Series\n", + "\n", + "Let's start by considering how we might represent two-dimensional data within a one-dimensional ``Series``.\n", + "For concreteness, we will consider a series of data where each point has a character and numerical key." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### The bad way\n", + "\n", + "Suppose you would like to track data about states from two different years.\n", + "Using the Pandas tools we've already covered, you might be tempted to simply use Python tuples as keys:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(California, 2000) 33871648\n", + "(California, 2010) 37253956\n", + "(New York, 2000) 18976457\n", + "(New York, 2010) 19378102\n", + "(Texas, 2000) 20851820\n", + "(Texas, 2010) 25145561\n", + "dtype: int64" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "index = [('California', 2000), ('California', 2010),\n", + " ('New York', 2000), ('New York', 2010),\n", + " ('Texas', 2000), ('Texas', 2010)]\n", + "populations = [33871648, 37253956,\n", + " 18976457, 19378102,\n", + " 20851820, 25145561]\n", + "pop = pd.Series(populations, index=index)\n", + "pop" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "With this indexing scheme, you can straightforwardly index or slice the series based on this multiple index:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(California, 2010) 37253956\n", + "(New York, 2000) 18976457\n", + "(New York, 2010) 19378102\n", + "(Texas, 2000) 20851820\n", + "dtype: int64" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pop[('California', 2010):('Texas', 2000)]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "But the convenience ends there. For example, if you need to select all values from 2010, you'll need to do some messy (and potentially slow) munging to make it happen:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(California, 2010) 37253956\n", + "(New York, 2010) 19378102\n", + "(Texas, 2010) 25145561\n", + "dtype: int64" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pop[[i for i in pop.index if i[1] == 2010]]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This produces the desired result, but is not as clean (or as efficient for large datasets) as the slicing syntax we've grown to love in Pandas." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### The Better Way: Pandas MultiIndex\n", + "Fortunately, Pandas provides a better way.\n", + "Our tuple-based indexing is essentially a rudimentary multi-index, and the Pandas ``MultiIndex`` type gives us the type of operations we wish to have.\n", + "We can create a multi-index from the tuples as follows:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "MultiIndex(levels=[['California', 'New York', 'Texas'], [2000, 2010]],\n", + " labels=[[0, 0, 1, 1, 2, 2], [0, 1, 0, 1, 0, 1]])" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "index = pd.MultiIndex.from_tuples(index)\n", + "index" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Notice that the ``MultiIndex`` contains multiple *levels* of indexing–in this case, the state names and the years, as well as multiple *labels* for each data point which encode these levels.\n", + "\n", + "If we re-index our series with this ``MultiIndex``, we see the hierarchical representation of the data:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "California 2000 33871648\n", + " 2010 37253956\n", + "New York 2000 18976457\n", + " 2010 19378102\n", + "Texas 2000 20851820\n", + " 2010 25145561\n", + "dtype: int64" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pop = pop.reindex(index)\n", + "pop" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here the first two columns of the ``Series`` representation show the multiple index values, while the third column shows the data.\n", + "Notice that some entries are missing in the first column: in this multi-index representation, any blank entry indicates the same value as the line above it." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now to access all data for which the second index is 2010, we can simply use the Pandas slicing notation:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "California 37253956\n", + "New York 19378102\n", + "Texas 25145561\n", + "dtype: int64" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pop[:, 2010]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The result is a singly indexed array with just the keys we're interested in.\n", + "This syntax is much more convenient (and the operation is much more efficient!) than the home-spun tuple-based multi-indexing solution that we started with.\n", + "We'll now further discuss this sort of indexing operation on hieararchically indexed data." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### MultiIndex as extra dimension\n", + "\n", + "You might notice something else here: we could easily have stored the same data using a simple ``DataFrame`` with index and column labels.\n", + "In fact, Pandas is built with this equivalence in mind. The ``unstack()`` method will quickly convert a multiply indexed ``Series`` into a conventionally indexed ``DataFrame``:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
20002010
California3387164837253956
New York1897645719378102
Texas2085182025145561
\n", + "
" + ], + "text/plain": [ + " 2000 2010\n", + "California 33871648 37253956\n", + "New York 18976457 19378102\n", + "Texas 20851820 25145561" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pop_df = pop.unstack()\n", + "pop_df" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Naturally, the ``stack()`` method provides the opposite operation:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "California 2000 33871648\n", + " 2010 37253956\n", + "New York 2000 18976457\n", + " 2010 19378102\n", + "Texas 2000 20851820\n", + " 2010 25145561\n", + "dtype: int64" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pop_df.stack()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Seeing this, you might wonder why would we would bother with hierarchical indexing at all.\n", + "The reason is simple: just as we were able to use multi-indexing to represent two-dimensional data within a one-dimensional ``Series``, we can also use it to represent data of three or more dimensions in a ``Series`` or ``DataFrame``.\n", + "Each extra level in a multi-index represents an extra dimension of data; taking advantage of this property gives us much more flexibility in the types of data we can represent. Concretely, we might want to add another column of demographic data for each state at each year (say, population under 18) ; with a ``MultiIndex`` this is as easy as adding another column to the ``DataFrame``:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
totalunder18
California2000338716489267089
2010372539569284094
New York2000189764574687374
2010193781024318033
Texas2000208518205906301
2010251455616879014
\n", + "
" + ], + "text/plain": [ + " total under18\n", + "California 2000 33871648 9267089\n", + " 2010 37253956 9284094\n", + "New York 2000 18976457 4687374\n", + " 2010 19378102 4318033\n", + "Texas 2000 20851820 5906301\n", + " 2010 25145561 6879014" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pop_df = pd.DataFrame({'total': pop,\n", + " 'under18': [9267089, 9284094,\n", + " 4687374, 4318033,\n", + " 5906301, 6879014]})\n", + "pop_df" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In addition, all the ufuncs and other functionality discussed in [Operating on Data in Pandas](03.03-Operations-in-Pandas.ipynb) work with hierarchical indices as well.\n", + "Here we compute the fraction of people under 18 by year, given the above data:" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
20002010
California0.2735940.249211
New York0.2470100.222831
Texas0.2832510.273568
\n", + "
" + ], + "text/plain": [ + " 2000 2010\n", + "California 0.273594 0.249211\n", + "New York 0.247010 0.222831\n", + "Texas 0.283251 0.273568" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "f_u18 = pop_df['under18'] / pop_df['total']\n", + "f_u18.unstack()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This allows us to easily and quickly manipulate and explore even high-dimensional data." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Methods of MultiIndex Creation\n", + "\n", + "The most straightforward way to construct a multiply indexed ``Series`` or ``DataFrame`` is to simply pass a list of two or more index arrays to the constructor. For example:" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
data1data2
a10.5542330.356072
20.9252440.219474
b10.4417590.610054
20.1714950.886688
\n", + "
" + ], + "text/plain": [ + " data1 data2\n", + "a 1 0.554233 0.356072\n", + " 2 0.925244 0.219474\n", + "b 1 0.441759 0.610054\n", + " 2 0.171495 0.886688" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df = pd.DataFrame(np.random.rand(4, 2),\n", + " index=[['a', 'a', 'b', 'b'], [1, 2, 1, 2]],\n", + " columns=['data1', 'data2'])\n", + "df" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The work of creating the ``MultiIndex`` is done in the background.\n", + "\n", + "Similarly, if you pass a dictionary with appropriate tuples as keys, Pandas will automatically recognize this and use a ``MultiIndex`` by default:" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "California 2000 33871648\n", + " 2010 37253956\n", + "New York 2000 18976457\n", + " 2010 19378102\n", + "Texas 2000 20851820\n", + " 2010 25145561\n", + "dtype: int64" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data = {('California', 2000): 33871648,\n", + " ('California', 2010): 37253956,\n", + " ('Texas', 2000): 20851820,\n", + " ('Texas', 2010): 25145561,\n", + " ('New York', 2000): 18976457,\n", + " ('New York', 2010): 19378102}\n", + "pd.Series(data)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Nevertheless, it is sometimes useful to explicitly create a ``MultiIndex``; we'll see a couple of these methods here." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Explicit MultiIndex constructors\n", + "\n", + "For more flexibility in how the index is constructed, you can instead use the class method constructors available in the ``pd.MultiIndex``.\n", + "For example, as we did before, you can construct the ``MultiIndex`` from a simple list of arrays giving the index values within each level:" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "MultiIndex(levels=[['a', 'b'], [1, 2]],\n", + " labels=[[0, 0, 1, 1], [0, 1, 0, 1]])" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pd.MultiIndex.from_arrays([['a', 'a', 'b', 'b'], [1, 2, 1, 2]])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can construct it from a list of tuples giving the multiple index values of each point:" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "MultiIndex(levels=[['a', 'b'], [1, 2]],\n", + " labels=[[0, 0, 1, 1], [0, 1, 0, 1]])" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pd.MultiIndex.from_tuples([('a', 1), ('a', 2), ('b', 1), ('b', 2)])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can even construct it from a Cartesian product of single indices:" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "MultiIndex(levels=[['a', 'b'], [1, 2]],\n", + " labels=[[0, 0, 1, 1], [0, 1, 0, 1]])" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pd.MultiIndex.from_product([['a', 'b'], [1, 2]])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Similarly, you can construct the ``MultiIndex`` directly using its internal encoding by passing ``levels`` (a list of lists containing available index values for each level) and ``labels`` (a list of lists that reference these labels):" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "MultiIndex(levels=[['a', 'b'], [1, 2]],\n", + " labels=[[0, 0, 1, 1], [0, 1, 0, 1]])" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pd.MultiIndex(levels=[['a', 'b'], [1, 2]],\n", + " labels=[[0, 0, 1, 1], [0, 1, 0, 1]])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Any of these objects can be passed as the ``index`` argument when creating a ``Series`` or ``Dataframe``, or be passed to the ``reindex`` method of an existing ``Series`` or ``DataFrame``." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### MultiIndex level names\n", + "\n", + "Sometimes it is convenient to name the levels of the ``MultiIndex``.\n", + "This can be accomplished by passing the ``names`` argument to any of the above ``MultiIndex`` constructors, or by setting the ``names`` attribute of the index after the fact:" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "state year\n", + "California 2000 33871648\n", + " 2010 37253956\n", + "New York 2000 18976457\n", + " 2010 19378102\n", + "Texas 2000 20851820\n", + " 2010 25145561\n", + "dtype: int64" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pop.index.names = ['state', 'year']\n", + "pop" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "With more involved datasets, this can be a useful way to keep track of the meaning of various index values." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### MultiIndex for columns\n", + "\n", + "In a ``DataFrame``, the rows and columns are completely symmetric, and just as the rows can have multiple levels of indices, the columns can have multiple levels as well.\n", + "Consider the following, which is a mock-up of some (somewhat realistic) medical data:" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
subjectBobGuidoSue
typeHRTempHRTempHRTemp
yearvisit
2013131.038.732.036.735.037.2
244.037.750.035.029.036.7
2014130.037.439.037.861.036.9
247.037.848.037.351.036.5
\n", + "
" + ], + "text/plain": [ + "subject Bob Guido Sue \n", + "type HR Temp HR Temp HR Temp\n", + "year visit \n", + "2013 1 31.0 38.7 32.0 36.7 35.0 37.2\n", + " 2 44.0 37.7 50.0 35.0 29.0 36.7\n", + "2014 1 30.0 37.4 39.0 37.8 61.0 36.9\n", + " 2 47.0 37.8 48.0 37.3 51.0 36.5" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# hierarchical indices and columns\n", + "index = pd.MultiIndex.from_product([[2013, 2014], [1, 2]],\n", + " names=['year', 'visit'])\n", + "columns = pd.MultiIndex.from_product([['Bob', 'Guido', 'Sue'], ['HR', 'Temp']],\n", + " names=['subject', 'type'])\n", + "\n", + "# mock some data\n", + "data = np.round(np.random.randn(4, 6), 1)\n", + "data[:, ::2] *= 10\n", + "data += 37\n", + "\n", + "# create the DataFrame\n", + "health_data = pd.DataFrame(data, index=index, columns=columns)\n", + "health_data" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here we see where the multi-indexing for both rows and columns can come in *very* handy.\n", + "This is fundamentally four-dimensional data, where the dimensions are the subject, the measurement type, the year, and the visit number.\n", + "With this in place we can, for example, index the top-level column by the person's name and get a full ``DataFrame`` containing just that person's information:" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
typeHRTemp
yearvisit
2013132.036.7
250.035.0
2014139.037.8
248.037.3
\n", + "
" + ], + "text/plain": [ + "type HR Temp\n", + "year visit \n", + "2013 1 32.0 36.7\n", + " 2 50.0 35.0\n", + "2014 1 39.0 37.8\n", + " 2 48.0 37.3" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "health_data['Guido']" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For complicated records containing multiple labeled measurements across multiple times for many subjects (people, countries, cities, etc.) use of hierarchical rows and columns can be extremely convenient!" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Indexing and Slicing a MultiIndex\n", + "\n", + "Indexing and slicing on a ``MultiIndex`` is designed to be intuitive, and it helps if you think about the indices as added dimensions.\n", + "We'll first look at indexing multiply indexed ``Series``, and then multiply-indexed ``DataFrame``s." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Multiply indexed Series\n", + "\n", + "Consider the multiply indexed ``Series`` of state populations we saw earlier:" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "state year\n", + "California 2000 33871648\n", + " 2010 37253956\n", + "New York 2000 18976457\n", + " 2010 19378102\n", + "Texas 2000 20851820\n", + " 2010 25145561\n", + "dtype: int64" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pop" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can access single elements by indexing with multiple terms:" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "33871648" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pop['California', 2000]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The ``MultiIndex`` also supports *partial indexing*, or indexing just one of the levels in the index.\n", + "The result is another ``Series``, with the lower-level indices maintained:" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "year\n", + "2000 33871648\n", + "2010 37253956\n", + "dtype: int64" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pop['California']" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Partial slicing is available as well, as long as the ``MultiIndex`` is sorted (see discussion in [Sorted and Unsorted Indices](Sorted-and-Unsorted-Indices)):" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "state year\n", + "California 2000 33871648\n", + " 2010 37253956\n", + "New York 2000 18976457\n", + " 2010 19378102\n", + "dtype: int64" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pop.loc['California':'New York']" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "With sorted indices, partial indexing can be performed on lower levels by passing an empty slice in the first index:" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "state\n", + "California 33871648\n", + "New York 18976457\n", + "Texas 20851820\n", + "dtype: int64" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pop[:, 2000]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Other types of indexing and selection (discussed in [Data Indexing and Selection](03.02-Data-Indexing-and-Selection.ipynb)) work as well; for example, selection based on Boolean masks:" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "state year\n", + "California 2000 33871648\n", + " 2010 37253956\n", + "Texas 2010 25145561\n", + "dtype: int64" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pop[pop > 22000000]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Selection based on fancy indexing also works:" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "state year\n", + "California 2000 33871648\n", + " 2010 37253956\n", + "Texas 2000 20851820\n", + " 2010 25145561\n", + "dtype: int64" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pop[['California', 'Texas']]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Multiply indexed DataFrames\n", + "\n", + "A multiply indexed ``DataFrame`` behaves in a similar manner.\n", + "Consider our toy medical ``DataFrame`` from before:" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
subjectBobGuidoSue
typeHRTempHRTempHRTemp
yearvisit
2013131.038.732.036.735.037.2
244.037.750.035.029.036.7
2014130.037.439.037.861.036.9
247.037.848.037.351.036.5
\n", + "
" + ], + "text/plain": [ + "subject Bob Guido Sue \n", + "type HR Temp HR Temp HR Temp\n", + "year visit \n", + "2013 1 31.0 38.7 32.0 36.7 35.0 37.2\n", + " 2 44.0 37.7 50.0 35.0 29.0 36.7\n", + "2014 1 30.0 37.4 39.0 37.8 61.0 36.9\n", + " 2 47.0 37.8 48.0 37.3 51.0 36.5" + ] + }, + "execution_count": 28, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "health_data" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Remember that columns are primary in a ``DataFrame``, and the syntax used for multiply indexed ``Series`` applies to the columns.\n", + "For example, we can recover Guido's heart rate data with a simple operation:" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "year visit\n", + "2013 1 32.0\n", + " 2 50.0\n", + "2014 1 39.0\n", + " 2 48.0\n", + "Name: (Guido, HR), dtype: float64" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "health_data['Guido', 'HR']" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Also, as with the single-index case, we can use the ``loc``, ``iloc``, and ``ix`` indexers introduced in [Data Indexing and Selection](03.02-Data-Indexing-and-Selection.ipynb). For example:" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
subjectBob
typeHRTemp
yearvisit
2013131.038.7
244.037.7
\n", + "
" + ], + "text/plain": [ + "subject Bob \n", + "type HR Temp\n", + "year visit \n", + "2013 1 31.0 38.7\n", + " 2 44.0 37.7" + ] + }, + "execution_count": 30, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "health_data.iloc[:2, :2]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "These indexers provide an array-like view of the underlying two-dimensional data, but each individual index in ``loc`` or ``iloc`` can be passed a tuple of multiple indices. For example:" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "year visit\n", + "2013 1 31.0\n", + " 2 44.0\n", + "2014 1 30.0\n", + " 2 47.0\n", + "Name: (Bob, HR), dtype: float64" + ] + }, + "execution_count": 31, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "health_data.loc[:, ('Bob', 'HR')]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Working with slices within these index tuples is not especially convenient; trying to create a slice within a tuple will lead to a syntax error:" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "ename": "SyntaxError", + "evalue": "invalid syntax (, line 1)", + "output_type": "error", + "traceback": [ + "\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m health_data.loc[(:, 1), (:, 'HR')]\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n" + ] + } + ], + "source": [ + "health_data.loc[(:, 1), (:, 'HR')]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You could get around this by building the desired slice explicitly using Python's built-in ``slice()`` function, but a better way in this context is to use an ``IndexSlice`` object, which Pandas provides for precisely this situation.\n", + "For example:" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
subjectBobGuidoSue
typeHRHRHR
yearvisit
2013131.032.035.0
2014130.039.061.0
\n", + "
" + ], + "text/plain": [ + "subject Bob Guido Sue\n", + "type HR HR HR\n", + "year visit \n", + "2013 1 31.0 32.0 35.0\n", + "2014 1 30.0 39.0 61.0" + ] + }, + "execution_count": 33, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "idx = pd.IndexSlice\n", + "health_data.loc[idx[:, 1], idx[:, 'HR']]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "There are so many ways to interact with data in multiply indexed ``Series`` and ``DataFrame``s, and as with many tools in this book the best way to become familiar with them is to try them out!" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Rearranging Multi-Indices\n", + "\n", + "One of the keys to working with multiply indexed data is knowing how to effectively transform the data.\n", + "There are a number of operations that will preserve all the information in the dataset, but rearrange it for the purposes of various computations.\n", + "We saw a brief example of this in the ``stack()`` and ``unstack()`` methods, but there are many more ways to finely control the rearrangement of data between hierarchical indices and columns, and we'll explore them here." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Sorted and unsorted indices\n", + "\n", + "Earlier, we briefly mentioned a caveat, but we should emphasize it more here.\n", + "*Many of the ``MultiIndex`` slicing operations will fail if the index is not sorted.*\n", + "Let's take a look at this here.\n", + "\n", + "We'll start by creating some simple multiply indexed data where the indices are *not lexographically sorted*:" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "char int\n", + "a 1 0.003001\n", + " 2 0.164974\n", + "c 1 0.741650\n", + " 2 0.569264\n", + "b 1 0.001693\n", + " 2 0.526226\n", + "dtype: float64" + ] + }, + "execution_count": 34, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "index = pd.MultiIndex.from_product([['a', 'c', 'b'], [1, 2]])\n", + "data = pd.Series(np.random.rand(6), index=index)\n", + "data.index.names = ['char', 'int']\n", + "data" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If we try to take a partial slice of this index, it will result in an error:" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "'Key length (1) was greater than MultiIndex lexsort depth (0)'\n" + ] + } + ], + "source": [ + "try:\n", + " data['a':'b']\n", + "except KeyError as e:\n", + " print(type(e))\n", + " print(e)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Although it is not entirely clear from the error message, this is the result of the MultiIndex not being sorted.\n", + "For various reasons, partial slices and other similar operations require the levels in the ``MultiIndex`` to be in sorted (i.e., lexographical) order.\n", + "Pandas provides a number of convenience routines to perform this type of sorting; examples are the ``sort_index()`` and ``sortlevel()`` methods of the ``DataFrame``.\n", + "We'll use the simplest, ``sort_index()``, here:" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "char int\n", + "a 1 0.003001\n", + " 2 0.164974\n", + "b 1 0.001693\n", + " 2 0.526226\n", + "c 1 0.741650\n", + " 2 0.569264\n", + "dtype: float64" + ] + }, + "execution_count": 36, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data = data.sort_index()\n", + "data" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "With the index sorted in this way, partial slicing will work as expected:" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "char int\n", + "a 1 0.003001\n", + " 2 0.164974\n", + "b 1 0.001693\n", + " 2 0.526226\n", + "dtype: float64" + ] + }, + "execution_count": 37, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data['a':'b']" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Stacking and unstacking indices\n", + "\n", + "As we saw briefly before, it is possible to convert a dataset from a stacked multi-index to a simple two-dimensional representation, optionally specifying the level to use:" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
stateCaliforniaNew YorkTexas
year
2000338716481897645720851820
2010372539561937810225145561
\n", + "
" + ], + "text/plain": [ + "state California New York Texas\n", + "year \n", + "2000 33871648 18976457 20851820\n", + "2010 37253956 19378102 25145561" + ] + }, + "execution_count": 38, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pop.unstack(level=0)" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
year20002010
state
California3387164837253956
New York1897645719378102
Texas2085182025145561
\n", + "
" + ], + "text/plain": [ + "year 2000 2010\n", + "state \n", + "California 33871648 37253956\n", + "New York 18976457 19378102\n", + "Texas 20851820 25145561" + ] + }, + "execution_count": 39, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pop.unstack(level=1)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The opposite of ``unstack()`` is ``stack()``, which here can be used to recover the original series:" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "state year\n", + "California 2000 33871648\n", + " 2010 37253956\n", + "New York 2000 18976457\n", + " 2010 19378102\n", + "Texas 2000 20851820\n", + " 2010 25145561\n", + "dtype: int64" + ] + }, + "execution_count": 40, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pop.unstack().stack()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Index setting and resetting\n", + "\n", + "Another way to rearrange hierarchical data is to turn the index labels into columns; this can be accomplished with the ``reset_index`` method.\n", + "Calling this on the population dictionary will result in a ``DataFrame`` with a *state* and *year* column holding the information that was formerly in the index.\n", + "For clarity, we can optionally specify the name of the data for the column representation:" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
stateyearpopulation
0California200033871648
1California201037253956
2New York200018976457
3New York201019378102
4Texas200020851820
5Texas201025145561
\n", + "
" + ], + "text/plain": [ + " state year population\n", + "0 California 2000 33871648\n", + "1 California 2010 37253956\n", + "2 New York 2000 18976457\n", + "3 New York 2010 19378102\n", + "4 Texas 2000 20851820\n", + "5 Texas 2010 25145561" + ] + }, + "execution_count": 41, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pop_flat = pop.reset_index(name='population')\n", + "pop_flat" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Often when working with data in the real world, the raw input data looks like this and it's useful to build a ``MultiIndex`` from the column values.\n", + "This can be done with the ``set_index`` method of the ``DataFrame``, which returns a multiply indexed ``DataFrame``:" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
population
stateyear
California200033871648
201037253956
New York200018976457
201019378102
Texas200020851820
201025145561
\n", + "
" + ], + "text/plain": [ + " population\n", + "state year \n", + "California 2000 33871648\n", + " 2010 37253956\n", + "New York 2000 18976457\n", + " 2010 19378102\n", + "Texas 2000 20851820\n", + " 2010 25145561" + ] + }, + "execution_count": 42, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pop_flat.set_index(['state', 'year'])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In practice, I find this type of reindexing to be one of the more useful patterns when encountering real-world datasets." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Data Aggregations on Multi-Indices\n", + "\n", + "We've previously seen that Pandas has built-in data aggregation methods, such as ``mean()``, ``sum()``, and ``max()``.\n", + "For hierarchically indexed data, these can be passed a ``level`` parameter that controls which subset of the data the aggregate is computed on.\n", + "\n", + "For example, let's return to our health data:" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
subjectBobGuidoSue
typeHRTempHRTempHRTemp
yearvisit
2013131.038.732.036.735.037.2
244.037.750.035.029.036.7
2014130.037.439.037.861.036.9
247.037.848.037.351.036.5
\n", + "
" + ], + "text/plain": [ + "subject Bob Guido Sue \n", + "type HR Temp HR Temp HR Temp\n", + "year visit \n", + "2013 1 31.0 38.7 32.0 36.7 35.0 37.2\n", + " 2 44.0 37.7 50.0 35.0 29.0 36.7\n", + "2014 1 30.0 37.4 39.0 37.8 61.0 36.9\n", + " 2 47.0 37.8 48.0 37.3 51.0 36.5" + ] + }, + "execution_count": 43, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "health_data" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Perhaps we'd like to average-out the measurements in the two visits each year. We can do this by naming the index level we'd like to explore, in this case the year:" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
subjectBobGuidoSue
typeHRTempHRTempHRTemp
year
201337.538.241.035.8532.036.95
201438.537.643.537.5556.036.70
\n", + "
" + ], + "text/plain": [ + "subject Bob Guido Sue \n", + "type HR Temp HR Temp HR Temp\n", + "year \n", + "2013 37.5 38.2 41.0 35.85 32.0 36.95\n", + "2014 38.5 37.6 43.5 37.55 56.0 36.70" + ] + }, + "execution_count": 44, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data_mean = health_data.mean(level='year')\n", + "data_mean" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "By further making use of the ``axis`` keyword, we can take the mean among levels on the columns as well:" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
typeHRTemp
year
201336.83333337.000000
201446.00000037.283333
\n", + "
" + ], + "text/plain": [ + "type HR Temp\n", + "year \n", + "2013 36.833333 37.000000\n", + "2014 46.000000 37.283333" + ] + }, + "execution_count": 45, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data_mean.mean(axis=1, level='type')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Thus in two lines, we've been able to find the average heart rate and temperature measured among all subjects in all visits each year.\n", + "This syntax is actually a short cut to the ``GroupBy`` functionality, which we will discuss in [Aggregation and Grouping](03.08-Aggregation-and-Grouping.ipynb).\n", + "While this is a toy example, many real-world datasets have similar hierarchical structure." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Aside: Panel Data\n", + "\n", + "Pandas has a few other fundamental data structures that we have not yet discussed, namely the ``pd.Panel`` and ``pd.Panel4D`` objects.\n", + "These can be thought of, respectively, as three-dimensional and four-dimensional generalizations of the (one-dimensional) ``Series`` and (two-dimensional) ``DataFrame`` structures.\n", + "Once you are familiar with indexing and manipulation of data in a ``Series`` and ``DataFrame``, ``Panel`` and ``Panel4D`` are relatively straightforward to use.\n", + "In particular, the ``ix``, ``loc``, and ``iloc`` indexers discussed in [Data Indexing and Selection](03.02-Data-Indexing-and-Selection.ipynb) extend readily to these higher-dimensional structures.\n", + "\n", + "We won't cover these panel structures further in this text, as I've found in the majority of cases that multi-indexing is a more useful and conceptually simpler representation for higher-dimensional data.\n", + "Additionally, panel data is fundamentally a dense data representation, while multi-indexing is fundamentally a sparse data representation.\n", + "As the number of dimensions increases, the dense representation can become very inefficient for the majority of real-world datasets.\n", + "For the occasional specialized application, however, these structures can be useful.\n", + "If you'd like to read more about the ``Panel`` and ``Panel4D`` structures, see the references listed in [Further Resources](03.13-Further-Resources.ipynb)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "< [Handling Missing Data](03.04-Missing-Values.ipynb) | [Contents](Index.ipynb) | [Combining Datasets: Concat and Append](03.06-Concat-And-Append.ipynb) >" + ] + } + ], + "metadata": { + "anaconda-cloud": {}, + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.4.3" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/pandas/03.06-Concat-And-Append.ipynb b/pandas/03.06-Concat-And-Append.ipynb new file mode 100644 index 0000000..efeaaff --- /dev/null +++ b/pandas/03.06-Concat-And-Append.ipynb @@ -0,0 +1,1637 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "\n", + "*This notebook contains an excerpt from the [Python Data Science Handbook](http://shop.oreilly.com/product/0636920034919.do) by Jake VanderPlas; the content is available [on GitHub](https://github.com/jakevdp/PythonDataScienceHandbook).*\n", + "\n", + "*The text is released under the [CC-BY-NC-ND license](https://creativecommons.org/licenses/by-nc-nd/3.0/us/legalcode), and code is released under the [MIT license](https://opensource.org/licenses/MIT). If you find this content useful, please consider supporting the work by [buying the book](http://shop.oreilly.com/product/0636920034919.do)!*\n", + "\n", + "*No changes were made to the contents of this notebook from the original.*" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "< [Hierarchical Indexing](03.05-Hierarchical-Indexing.ipynb) | [Contents](Index.ipynb) | [Combining Datasets: Merge and Join](03.07-Merge-and-Join.ipynb) >" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Combining Datasets: Concat and Append" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Some of the most interesting studies of data come from combining different data sources.\n", + "These operations can involve anything from very straightforward concatenation of two different datasets, to more complicated database-style joins and merges that correctly handle any overlaps between the datasets.\n", + "``Series`` and ``DataFrame``s are built with this type of operation in mind, and Pandas includes functions and methods that make this sort of data wrangling fast and straightforward.\n", + "\n", + "Here we'll take a look at simple concatenation of ``Series`` and ``DataFrame``s with the ``pd.concat`` function; later we'll dive into more sophisticated in-memory merges and joins implemented in Pandas.\n", + "\n", + "We begin with the standard imports:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import pandas as pd\n", + "import numpy as np" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For convenience, we'll define this function which creates a ``DataFrame`` of a particular form that will be useful below:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ABC
0A0B0C0
1A1B1C1
2A2B2C2
\n", + "
" + ], + "text/plain": [ + " A B C\n", + "0 A0 B0 C0\n", + "1 A1 B1 C1\n", + "2 A2 B2 C2" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def make_df(cols, ind):\n", + " \"\"\"Quickly make a DataFrame\"\"\"\n", + " data = {c: [str(c) + str(i) for i in ind]\n", + " for c in cols}\n", + " return pd.DataFrame(data, ind)\n", + "\n", + "# example DataFrame\n", + "make_df('ABC', range(3))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In addition, we'll create a quick class that allows us to display multiple ``DataFrame``s side by side. The code makes use of the special ``_repr_html_`` method, which IPython uses to implement its rich object display:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "class display(object):\n", + " \"\"\"Display HTML representation of multiple objects\"\"\"\n", + " template = \"\"\"
\n", + "

{0}

{1}\n", + "
\"\"\"\n", + " def __init__(self, *args):\n", + " self.args = args\n", + " \n", + " def _repr_html_(self):\n", + " return '\\n'.join(self.template.format(a, eval(a)._repr_html_())\n", + " for a in self.args)\n", + " \n", + " def __repr__(self):\n", + " return '\\n\\n'.join(a + '\\n' + repr(eval(a))\n", + " for a in self.args)\n", + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The use of this will become clearer as we continue our discussion in the following section." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Recall: Concatenation of NumPy Arrays\n", + "\n", + "Concatenation of ``Series`` and ``DataFrame`` objects is very similar to concatenation of Numpy arrays, which can be done via the ``np.concatenate`` function as discussed in [The Basics of NumPy Arrays](02.02-The-Basics-Of-NumPy-Arrays.ipynb).\n", + "Recall that with it, you can combine the contents of two or more arrays into a single array:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([1, 2, 3, 4, 5, 6, 7, 8, 9])" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "x = [1, 2, 3]\n", + "y = [4, 5, 6]\n", + "z = [7, 8, 9]\n", + "np.concatenate([x, y, z])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The first argument is a list or tuple of arrays to concatenate.\n", + "Additionally, it takes an ``axis`` keyword that allows you to specify the axis along which the result will be concatenated:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[1, 2, 1, 2],\n", + " [3, 4, 3, 4]])" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "x = [[1, 2],\n", + " [3, 4]]\n", + "np.concatenate([x, x], axis=1)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Simple Concatenation with ``pd.concat``" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Pandas has a function, ``pd.concat()``, which has a similar syntax to ``np.concatenate`` but contains a number of options that we'll discuss momentarily:\n", + "\n", + "```python\n", + "# Signature in Pandas v0.18\n", + "pd.concat(objs, axis=0, join='outer', join_axes=None, ignore_index=False,\n", + " keys=None, levels=None, names=None, verify_integrity=False,\n", + " copy=True)\n", + "```\n", + "\n", + "``pd.concat()`` can be used for a simple concatenation of ``Series`` or ``DataFrame`` objects, just as ``np.concatenate()`` can be used for simple concatenations of arrays:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "1 A\n", + "2 B\n", + "3 C\n", + "4 D\n", + "5 E\n", + "6 F\n", + "dtype: object" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "ser1 = pd.Series(['A', 'B', 'C'], index=[1, 2, 3])\n", + "ser2 = pd.Series(['D', 'E', 'F'], index=[4, 5, 6])\n", + "pd.concat([ser1, ser2])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "It also works to concatenate higher-dimensional objects, such as ``DataFrame``s:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "

df1

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
AB
1A1B1
2A2B2
\n", + "
\n", + "
\n", + "
\n", + "

df2

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
AB
3A3B3
4A4B4
\n", + "
\n", + "
\n", + "
\n", + "

pd.concat([df1, df2])

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
AB
1A1B1
2A2B2
3A3B3
4A4B4
\n", + "
\n", + "
" + ], + "text/plain": [ + "df1\n", + " A B\n", + "1 A1 B1\n", + "2 A2 B2\n", + "\n", + "df2\n", + " A B\n", + "3 A3 B3\n", + "4 A4 B4\n", + "\n", + "pd.concat([df1, df2])\n", + " A B\n", + "1 A1 B1\n", + "2 A2 B2\n", + "3 A3 B3\n", + "4 A4 B4" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df1 = make_df('AB', [1, 2])\n", + "df2 = make_df('AB', [3, 4])\n", + "display('df1', 'df2', 'pd.concat([df1, df2])')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "By default, the concatenation takes place row-wise within the ``DataFrame`` (i.e., ``axis=0``).\n", + "Like ``np.concatenate``, ``pd.concat`` allows specification of an axis along which concatenation will take place.\n", + "Consider the following example:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "

df3

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
AB
0A0B0
1A1B1
\n", + "
\n", + "
\n", + "
\n", + "

df4

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
CD
0C0D0
1C1D1
\n", + "
\n", + "
\n", + "
\n", + "

pd.concat([df3, df4], axis='col')

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ABCD
0A0B0C0D0
1A1B1C1D1
\n", + "
\n", + "
" + ], + "text/plain": [ + "df3\n", + " A B\n", + "0 A0 B0\n", + "1 A1 B1\n", + "\n", + "df4\n", + " C D\n", + "0 C0 D0\n", + "1 C1 D1\n", + "\n", + "pd.concat([df3, df4], axis='col')\n", + " A B C D\n", + "0 A0 B0 C0 D0\n", + "1 A1 B1 C1 D1" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df3 = make_df('AB', [0, 1])\n", + "df4 = make_df('CD', [0, 1])\n", + "display('df3', 'df4', \"pd.concat([df3, df4], axis='col')\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We could have equivalently specified ``axis=1``; here we've used the more intuitive ``axis='col'``. " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Duplicate indices\n", + "\n", + "One important difference between ``np.concatenate`` and ``pd.concat`` is that Pandas concatenation *preserves indices*, even if the result will have duplicate indices!\n", + "Consider this simple example:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "

x

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
AB
0A0B0
1A1B1
\n", + "
\n", + "
\n", + "
\n", + "

y

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
AB
0A2B2
1A3B3
\n", + "
\n", + "
\n", + "
\n", + "

pd.concat([x, y])

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
AB
0A0B0
1A1B1
0A2B2
1A3B3
\n", + "
\n", + "
" + ], + "text/plain": [ + "x\n", + " A B\n", + "0 A0 B0\n", + "1 A1 B1\n", + "\n", + "y\n", + " A B\n", + "0 A2 B2\n", + "1 A3 B3\n", + "\n", + "pd.concat([x, y])\n", + " A B\n", + "0 A0 B0\n", + "1 A1 B1\n", + "0 A2 B2\n", + "1 A3 B3" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "x = make_df('AB', [0, 1])\n", + "y = make_df('AB', [2, 3])\n", + "y.index = x.index # make duplicate indices!\n", + "display('x', 'y', 'pd.concat([x, y])')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Notice the repeated indices in the result.\n", + "While this is valid within ``DataFrame``s, the outcome is often undesirable.\n", + "``pd.concat()`` gives us a few ways to handle it." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Catching the repeats as an error\n", + "\n", + "If you'd like to simply verify that the indices in the result of ``pd.concat()`` do not overlap, you can specify the ``verify_integrity`` flag.\n", + "With this set to True, the concatenation will raise an exception if there are duplicate indices.\n", + "Here is an example, where for clarity we'll catch and print the error message:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "ValueError: Indexes have overlapping values: [0, 1]\n" + ] + } + ], + "source": [ + "try:\n", + " pd.concat([x, y], verify_integrity=True)\n", + "except ValueError as e:\n", + " print(\"ValueError:\", e)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Ignoring the index\n", + "\n", + "Sometimes the index itself does not matter, and you would prefer it to simply be ignored.\n", + "This option can be specified using the ``ignore_index`` flag.\n", + "With this set to true, the concatenation will create a new integer index for the resulting ``Series``:" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "

x

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
AB
0A0B0
1A1B1
\n", + "
\n", + "
\n", + "
\n", + "

y

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
AB
0A2B2
1A3B3
\n", + "
\n", + "
\n", + "
\n", + "

pd.concat([x, y], ignore_index=True)

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
AB
0A0B0
1A1B1
2A2B2
3A3B3
\n", + "
\n", + "
" + ], + "text/plain": [ + "x\n", + " A B\n", + "0 A0 B0\n", + "1 A1 B1\n", + "\n", + "y\n", + " A B\n", + "0 A2 B2\n", + "1 A3 B3\n", + "\n", + "pd.concat([x, y], ignore_index=True)\n", + " A B\n", + "0 A0 B0\n", + "1 A1 B1\n", + "2 A2 B2\n", + "3 A3 B3" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "display('x', 'y', 'pd.concat([x, y], ignore_index=True)')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Adding MultiIndex keys\n", + "\n", + "Another option is to use the ``keys`` option to specify a label for the data sources; the result will be a hierarchically indexed series containing the data:" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "

x

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
AB
0A0B0
1A1B1
\n", + "
\n", + "
\n", + "
\n", + "

y

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
AB
0A2B2
1A3B3
\n", + "
\n", + "
\n", + "
\n", + "

pd.concat([x, y], keys=['x', 'y'])

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
AB
x0A0B0
1A1B1
y0A2B2
1A3B3
\n", + "
\n", + "
" + ], + "text/plain": [ + "x\n", + " A B\n", + "0 A0 B0\n", + "1 A1 B1\n", + "\n", + "y\n", + " A B\n", + "0 A2 B2\n", + "1 A3 B3\n", + "\n", + "pd.concat([x, y], keys=['x', 'y'])\n", + " A B\n", + "x 0 A0 B0\n", + " 1 A1 B1\n", + "y 0 A2 B2\n", + " 1 A3 B3" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "display('x', 'y', \"pd.concat([x, y], keys=['x', 'y'])\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The result is a multiply indexed ``DataFrame``, and we can use the tools discussed in [Hierarchical Indexing](03.05-Hierarchical-Indexing.ipynb) to transform this data into the representation we're interested in." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Concatenation with joins\n", + "\n", + "In the simple examples we just looked at, we were mainly concatenating ``DataFrame``s with shared column names.\n", + "In practice, data from different sources might have different sets of column names, and ``pd.concat`` offers several options in this case.\n", + "Consider the concatenation of the following two ``DataFrame``s, which have some (but not all!) columns in common:" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "

df5

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ABC
1A1B1C1
2A2B2C2
\n", + "
\n", + "
\n", + "
\n", + "

df6

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
BCD
3B3C3D3
4B4C4D4
\n", + "
\n", + "
\n", + "
\n", + "

pd.concat([df5, df6])

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ABCD
1A1B1C1NaN
2A2B2C2NaN
3NaNB3C3D3
4NaNB4C4D4
\n", + "
\n", + "
" + ], + "text/plain": [ + "df5\n", + " A B C\n", + "1 A1 B1 C1\n", + "2 A2 B2 C2\n", + "\n", + "df6\n", + " B C D\n", + "3 B3 C3 D3\n", + "4 B4 C4 D4\n", + "\n", + "pd.concat([df5, df6])\n", + " A B C D\n", + "1 A1 B1 C1 NaN\n", + "2 A2 B2 C2 NaN\n", + "3 NaN B3 C3 D3\n", + "4 NaN B4 C4 D4" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df5 = make_df('ABC', [1, 2])\n", + "df6 = make_df('BCD', [3, 4])\n", + "display('df5', 'df6', 'pd.concat([df5, df6])')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "By default, the entries for which no data is available are filled with NA values.\n", + "To change this, we can specify one of several options for the ``join`` and ``join_axes`` parameters of the concatenate function.\n", + "By default, the join is a union of the input columns (``join='outer'``), but we can change this to an intersection of the columns using ``join='inner'``:" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "

df5

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ABC
1A1B1C1
2A2B2C2
\n", + "
\n", + "
\n", + "
\n", + "

df6

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
BCD
3B3C3D3
4B4C4D4
\n", + "
\n", + "
\n", + "
\n", + "

pd.concat([df5, df6], join='inner')

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
BC
1B1C1
2B2C2
3B3C3
4B4C4
\n", + "
\n", + "
" + ], + "text/plain": [ + "df5\n", + " A B C\n", + "1 A1 B1 C1\n", + "2 A2 B2 C2\n", + "\n", + "df6\n", + " B C D\n", + "3 B3 C3 D3\n", + "4 B4 C4 D4\n", + "\n", + "pd.concat([df5, df6], join='inner')\n", + " B C\n", + "1 B1 C1\n", + "2 B2 C2\n", + "3 B3 C3\n", + "4 B4 C4" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "display('df5', 'df6',\n", + " \"pd.concat([df5, df6], join='inner')\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Another option is to directly specify the index of the remaininig colums using the ``join_axes`` argument, which takes a list of index objects.\n", + "Here we'll specify that the returned columns should be the same as those of the first input:" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "

df5

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ABC
1A1B1C1
2A2B2C2
\n", + "
\n", + "
\n", + "
\n", + "

df6

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
BCD
3B3C3D3
4B4C4D4
\n", + "
\n", + "
\n", + "
\n", + "

pd.concat([df5, df6], join_axes=[df5.columns])

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ABC
1A1B1C1
2A2B2C2
3NaNB3C3
4NaNB4C4
\n", + "
\n", + "
" + ], + "text/plain": [ + "df5\n", + " A B C\n", + "1 A1 B1 C1\n", + "2 A2 B2 C2\n", + "\n", + "df6\n", + " B C D\n", + "3 B3 C3 D3\n", + "4 B4 C4 D4\n", + "\n", + "pd.concat([df5, df6], join_axes=[df5.columns])\n", + " A B C\n", + "1 A1 B1 C1\n", + "2 A2 B2 C2\n", + "3 NaN B3 C3\n", + "4 NaN B4 C4" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "display('df5', 'df6',\n", + " \"pd.concat([df5, df6], join_axes=[df5.columns])\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The combination of options of the ``pd.concat`` function allows a wide range of possible behaviors when joining two datasets; keep these in mind as you use these tools for your own data." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### The ``append()`` method\n", + "\n", + "Because direct array concatenation is so common, ``Series`` and ``DataFrame`` objects have an ``append`` method that can accomplish the same thing in fewer keystrokes.\n", + "For example, rather than calling ``pd.concat([df1, df2])``, you can simply call ``df1.append(df2)``:" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "

df1

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
AB
1A1B1
2A2B2
\n", + "
\n", + "
\n", + "
\n", + "

df2

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
AB
3A3B3
4A4B4
\n", + "
\n", + "
\n", + "
\n", + "

df1.append(df2)

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
AB
1A1B1
2A2B2
3A3B3
4A4B4
\n", + "
\n", + "
" + ], + "text/plain": [ + "df1\n", + " A B\n", + "1 A1 B1\n", + "2 A2 B2\n", + "\n", + "df2\n", + " A B\n", + "3 A3 B3\n", + "4 A4 B4\n", + "\n", + "df1.append(df2)\n", + " A B\n", + "1 A1 B1\n", + "2 A2 B2\n", + "3 A3 B3\n", + "4 A4 B4" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "display('df1', 'df2', 'df1.append(df2)')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Keep in mind that unlike the ``append()`` and ``extend()`` methods of Python lists, the ``append()`` method in Pandas does not modify the original object–instead it creates a new object with the combined data.\n", + "It also is not a very efficient method, because it involves creation of a new index *and* data buffer.\n", + "Thus, if you plan to do multiple ``append`` operations, it is generally better to build a list of ``DataFrame``s and pass them all at once to the ``concat()`` function.\n", + "\n", + "In the next section, we'll look at another more powerful approach to combining data from multiple sources, the database-style merges/joins implemented in ``pd.merge``.\n", + "For more information on ``concat()``, ``append()``, and related functionality, see the [\"Merge, Join, and Concatenate\" section](http://pandas.pydata.org/pandas-docs/stable/merging.html) of the Pandas documentation." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "< [Hierarchical Indexing](03.05-Hierarchical-Indexing.ipynb) | [Contents](Index.ipynb) | [Combining Datasets: Merge and Join](03.07-Merge-and-Join.ipynb) >" + ] + } + ], + "metadata": { + "anaconda-cloud": {}, + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.4.3" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/pandas/03.07-Merge-and-Join.ipynb b/pandas/03.07-Merge-and-Join.ipynb new file mode 100644 index 0000000..5aa7fc7 --- /dev/null +++ b/pandas/03.07-Merge-and-Join.ipynb @@ -0,0 +1,3570 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "\n", + "*This notebook contains an excerpt from the [Python Data Science Handbook](http://shop.oreilly.com/product/0636920034919.do) by Jake VanderPlas; the content is available [on GitHub](https://github.com/jakevdp/PythonDataScienceHandbook).*\n", + "\n", + "*The text is released under the [CC-BY-NC-ND license](https://creativecommons.org/licenses/by-nc-nd/3.0/us/legalcode), and code is released under the [MIT license](https://opensource.org/licenses/MIT). If you find this content useful, please consider supporting the work by [buying the book](http://shop.oreilly.com/product/0636920034919.do)!*\n", + "\n", + "*No changes were made to the contents of this notebook from the original.*" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "< [Combining Datasets: Concat and Append](03.06-Concat-And-Append.ipynb) | [Contents](Index.ipynb) | [Aggregation and Grouping](03.08-Aggregation-and-Grouping.ipynb) >" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Combining Datasets: Merge and Join" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "One essential feature offered by Pandas is its high-performance, in-memory join and merge operations.\n", + "If you have ever worked with databases, you should be familiar with this type of data interaction.\n", + "The main interface for this is the ``pd.merge`` function, and we'll see few examples of how this can work in practice.\n", + "\n", + "For convenience, we will start by redefining the ``display()`` functionality from the previous section:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import pandas as pd\n", + "import numpy as np\n", + "\n", + "class display(object):\n", + " \"\"\"Display HTML representation of multiple objects\"\"\"\n", + " template = \"\"\"
\n", + "

{0}

{1}\n", + "
\"\"\"\n", + " def __init__(self, *args):\n", + " self.args = args\n", + " \n", + " def _repr_html_(self):\n", + " return '\\n'.join(self.template.format(a, eval(a)._repr_html_())\n", + " for a in self.args)\n", + " \n", + " def __repr__(self):\n", + " return '\\n\\n'.join(a + '\\n' + repr(eval(a))\n", + " for a in self.args)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Relational Algebra\n", + "\n", + "The behavior implemented in ``pd.merge()`` is a subset of what is known as *relational algebra*, which is a formal set of rules for manipulating relational data, and forms the conceptual foundation of operations available in most databases.\n", + "The strength of the relational algebra approach is that it proposes several primitive operations, which become the building blocks of more complicated operations on any dataset.\n", + "With this lexicon of fundamental operations implemented efficiently in a database or other program, a wide range of fairly complicated composite operations can be performed.\n", + "\n", + "Pandas implements several of these fundamental building-blocks in the ``pd.merge()`` function and the related ``join()`` method of ``Series`` and ``Dataframe``s.\n", + "As we will see, these let you efficiently link data from different sources." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Categories of Joins\n", + "\n", + "The ``pd.merge()`` function implements a number of types of joins: the *one-to-one*, *many-to-one*, and *many-to-many* joins.\n", + "All three types of joins are accessed via an identical call to the ``pd.merge()`` interface; the type of join performed depends on the form of the input data.\n", + "Here we will show simple examples of the three types of merges, and discuss detailed options further below." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### One-to-one joins\n", + "\n", + "Perhaps the simplest type of merge expresion is the one-to-one join, which is in many ways very similar to the column-wise concatenation seen in [Combining Datasets: Concat & Append](03.06-Concat-And-Append.ipynb).\n", + "As a concrete example, consider the following two ``DataFrames`` which contain information on several employees in a company:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "

df1

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
employeegroup
0BobAccounting
1JakeEngineering
2LisaEngineering
3SueHR
\n", + "
\n", + "
\n", + "
\n", + "

df2

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
employeehire_date
0Lisa2004
1Bob2008
2Jake2012
3Sue2014
\n", + "
\n", + "
" + ], + "text/plain": [ + "df1\n", + " employee group\n", + "0 Bob Accounting\n", + "1 Jake Engineering\n", + "2 Lisa Engineering\n", + "3 Sue HR\n", + "\n", + "df2\n", + " employee hire_date\n", + "0 Lisa 2004\n", + "1 Bob 2008\n", + "2 Jake 2012\n", + "3 Sue 2014" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df1 = pd.DataFrame({'employee': ['Bob', 'Jake', 'Lisa', 'Sue'],\n", + " 'group': ['Accounting', 'Engineering', 'Engineering', 'HR']})\n", + "df2 = pd.DataFrame({'employee': ['Lisa', 'Bob', 'Jake', 'Sue'],\n", + " 'hire_date': [2004, 2008, 2012, 2014]})\n", + "display('df1', 'df2')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To combine this information into a single ``DataFrame``, we can use the ``pd.merge()`` function:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
employeegrouphire_date
0BobAccounting2008
1JakeEngineering2012
2LisaEngineering2004
3SueHR2014
\n", + "
" + ], + "text/plain": [ + " employee group hire_date\n", + "0 Bob Accounting 2008\n", + "1 Jake Engineering 2012\n", + "2 Lisa Engineering 2004\n", + "3 Sue HR 2014" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df3 = pd.merge(df1, df2)\n", + "df3" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The ``pd.merge()`` function recognizes that each ``DataFrame`` has an \"employee\" column, and automatically joins using this column as a key.\n", + "The result of the merge is a new ``DataFrame`` that combines the information from the two inputs.\n", + "Notice that the order of entries in each column is not necessarily maintained: in this case, the order of the \"employee\" column differs between ``df1`` and ``df2``, and the ``pd.merge()`` function correctly accounts for this.\n", + "Additionally, keep in mind that the merge in general discards the index, except in the special case of merges by index (see the ``left_index`` and ``right_index`` keywords, discussed momentarily)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Many-to-one joins" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Many-to-one joins are joins in which one of the two key columns contains duplicate entries.\n", + "For the many-to-one case, the resulting ``DataFrame`` will preserve those duplicate entries as appropriate.\n", + "Consider the following example of a many-to-one join:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "

df3

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
employeegrouphire_date
0BobAccounting2008
1JakeEngineering2012
2LisaEngineering2004
3SueHR2014
\n", + "
\n", + "
\n", + "
\n", + "

df4

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
groupsupervisor
0AccountingCarly
1EngineeringGuido
2HRSteve
\n", + "
\n", + "
\n", + "
\n", + "

pd.merge(df3, df4)

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
employeegrouphire_datesupervisor
0BobAccounting2008Carly
1JakeEngineering2012Guido
2LisaEngineering2004Guido
3SueHR2014Steve
\n", + "
\n", + "
" + ], + "text/plain": [ + "df3\n", + " employee group hire_date\n", + "0 Bob Accounting 2008\n", + "1 Jake Engineering 2012\n", + "2 Lisa Engineering 2004\n", + "3 Sue HR 2014\n", + "\n", + "df4\n", + " group supervisor\n", + "0 Accounting Carly\n", + "1 Engineering Guido\n", + "2 HR Steve\n", + "\n", + "pd.merge(df3, df4)\n", + " employee group hire_date supervisor\n", + "0 Bob Accounting 2008 Carly\n", + "1 Jake Engineering 2012 Guido\n", + "2 Lisa Engineering 2004 Guido\n", + "3 Sue HR 2014 Steve" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df4 = pd.DataFrame({'group': ['Accounting', 'Engineering', 'HR'],\n", + " 'supervisor': ['Carly', 'Guido', 'Steve']})\n", + "display('df3', 'df4', 'pd.merge(df3, df4)')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The resulting ``DataFrame`` has an aditional column with the \"supervisor\" information, where the information is repeated in one or more locations as required by the inputs." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Many-to-many joins" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Many-to-many joins are a bit confusing conceptually, but are nevertheless well defined.\n", + "If the key column in both the left and right array contains duplicates, then the result is a many-to-many merge.\n", + "This will be perhaps most clear with a concrete example.\n", + "Consider the following, where we have a ``DataFrame`` showing one or more skills associated with a particular group.\n", + "By performing a many-to-many join, we can recover the skills associated with any individual person:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "

df1

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
employeegroup
0BobAccounting
1JakeEngineering
2LisaEngineering
3SueHR
\n", + "
\n", + "
\n", + "
\n", + "

df5

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
groupskills
0Accountingmath
1Accountingspreadsheets
2Engineeringcoding
3Engineeringlinux
4HRspreadsheets
5HRorganization
\n", + "
\n", + "
\n", + "
\n", + "

pd.merge(df1, df5)

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
employeegroupskills
0BobAccountingmath
1BobAccountingspreadsheets
2JakeEngineeringcoding
3JakeEngineeringlinux
4LisaEngineeringcoding
5LisaEngineeringlinux
6SueHRspreadsheets
7SueHRorganization
\n", + "
\n", + "
" + ], + "text/plain": [ + "df1\n", + " employee group\n", + "0 Bob Accounting\n", + "1 Jake Engineering\n", + "2 Lisa Engineering\n", + "3 Sue HR\n", + "\n", + "df5\n", + " group skills\n", + "0 Accounting math\n", + "1 Accounting spreadsheets\n", + "2 Engineering coding\n", + "3 Engineering linux\n", + "4 HR spreadsheets\n", + "5 HR organization\n", + "\n", + "pd.merge(df1, df5)\n", + " employee group skills\n", + "0 Bob Accounting math\n", + "1 Bob Accounting spreadsheets\n", + "2 Jake Engineering coding\n", + "3 Jake Engineering linux\n", + "4 Lisa Engineering coding\n", + "5 Lisa Engineering linux\n", + "6 Sue HR spreadsheets\n", + "7 Sue HR organization" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df5 = pd.DataFrame({'group': ['Accounting', 'Accounting',\n", + " 'Engineering', 'Engineering', 'HR', 'HR'],\n", + " 'skills': ['math', 'spreadsheets', 'coding', 'linux',\n", + " 'spreadsheets', 'organization']})\n", + "display('df1', 'df5', \"pd.merge(df1, df5)\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "These three types of joins can be used with other Pandas tools to implement a wide array of functionality.\n", + "But in practice, datasets are rarely as clean as the one we're working with here.\n", + "In the following section we'll consider some of the options provided by ``pd.merge()`` that enable you to tune how the join operations work." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Specification of the Merge Key" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We've already seen the default behavior of ``pd.merge()``: it looks for one or more matching column names between the two inputs, and uses this as the key.\n", + "However, often the column names will not match so nicely, and ``pd.merge()`` provides a variety of options for handling this." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### The ``on`` keyword\n", + "\n", + "Most simply, you can explicitly specify the name of the key column using the ``on`` keyword, which takes a column name or a list of column names:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "

df1

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
employeegroup
0BobAccounting
1JakeEngineering
2LisaEngineering
3SueHR
\n", + "
\n", + "
\n", + "
\n", + "

df2

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
employeehire_date
0Lisa2004
1Bob2008
2Jake2012
3Sue2014
\n", + "
\n", + "
\n", + "
\n", + "

pd.merge(df1, df2, on='employee')

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
employeegrouphire_date
0BobAccounting2008
1JakeEngineering2012
2LisaEngineering2004
3SueHR2014
\n", + "
\n", + "
" + ], + "text/plain": [ + "df1\n", + " employee group\n", + "0 Bob Accounting\n", + "1 Jake Engineering\n", + "2 Lisa Engineering\n", + "3 Sue HR\n", + "\n", + "df2\n", + " employee hire_date\n", + "0 Lisa 2004\n", + "1 Bob 2008\n", + "2 Jake 2012\n", + "3 Sue 2014\n", + "\n", + "pd.merge(df1, df2, on='employee')\n", + " employee group hire_date\n", + "0 Bob Accounting 2008\n", + "1 Jake Engineering 2012\n", + "2 Lisa Engineering 2004\n", + "3 Sue HR 2014" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "display('df1', 'df2', \"pd.merge(df1, df2, on='employee')\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This option works only if both the left and right ``DataFrame``s have the specified column name." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### The ``left_on`` and ``right_on`` keywords\n", + "\n", + "At times you may wish to merge two datasets with different column names; for example, we may have a dataset in which the employee name is labeled as \"name\" rather than \"employee\".\n", + "In this case, we can use the ``left_on`` and ``right_on`` keywords to specify the two column names:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "

df1

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
employeegroup
0BobAccounting
1JakeEngineering
2LisaEngineering
3SueHR
\n", + "
\n", + "
\n", + "
\n", + "

df3

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
namesalary
0Bob70000
1Jake80000
2Lisa120000
3Sue90000
\n", + "
\n", + "
\n", + "
\n", + "

pd.merge(df1, df3, left_on=\"employee\", right_on=\"name\")

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
employeegroupnamesalary
0BobAccountingBob70000
1JakeEngineeringJake80000
2LisaEngineeringLisa120000
3SueHRSue90000
\n", + "
\n", + "
" + ], + "text/plain": [ + "df1\n", + " employee group\n", + "0 Bob Accounting\n", + "1 Jake Engineering\n", + "2 Lisa Engineering\n", + "3 Sue HR\n", + "\n", + "df3\n", + " name salary\n", + "0 Bob 70000\n", + "1 Jake 80000\n", + "2 Lisa 120000\n", + "3 Sue 90000\n", + "\n", + "pd.merge(df1, df3, left_on=\"employee\", right_on=\"name\")\n", + " employee group name salary\n", + "0 Bob Accounting Bob 70000\n", + "1 Jake Engineering Jake 80000\n", + "2 Lisa Engineering Lisa 120000\n", + "3 Sue HR Sue 90000" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df3 = pd.DataFrame({'name': ['Bob', 'Jake', 'Lisa', 'Sue'],\n", + " 'salary': [70000, 80000, 120000, 90000]})\n", + "display('df1', 'df3', 'pd.merge(df1, df3, left_on=\"employee\", right_on=\"name\")')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The result has a redundant column that we can drop if desired–for example, by using the ``drop()`` method of ``DataFrame``s:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
employeegroupsalary
0BobAccounting70000
1JakeEngineering80000
2LisaEngineering120000
3SueHR90000
\n", + "
" + ], + "text/plain": [ + " employee group salary\n", + "0 Bob Accounting 70000\n", + "1 Jake Engineering 80000\n", + "2 Lisa Engineering 120000\n", + "3 Sue HR 90000" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pd.merge(df1, df3, left_on=\"employee\", right_on=\"name\").drop('name', axis=1)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### The ``left_index`` and ``right_index`` keywords\n", + "\n", + "Sometimes, rather than merging on a column, you would instead like to merge on an index.\n", + "For example, your data might look like this:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "

df1a

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
group
employee
BobAccounting
JakeEngineering
LisaEngineering
SueHR
\n", + "
\n", + "
\n", + "
\n", + "

df2a

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
hire_date
employee
Lisa2004
Bob2008
Jake2012
Sue2014
\n", + "
\n", + "
" + ], + "text/plain": [ + "df1a\n", + " group\n", + "employee \n", + "Bob Accounting\n", + "Jake Engineering\n", + "Lisa Engineering\n", + "Sue HR\n", + "\n", + "df2a\n", + " hire_date\n", + "employee \n", + "Lisa 2004\n", + "Bob 2008\n", + "Jake 2012\n", + "Sue 2014" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df1a = df1.set_index('employee')\n", + "df2a = df2.set_index('employee')\n", + "display('df1a', 'df2a')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can use the index as the key for merging by specifying the ``left_index`` and/or ``right_index`` flags in ``pd.merge()``:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "

df1a

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
group
employee
BobAccounting
JakeEngineering
LisaEngineering
SueHR
\n", + "
\n", + "
\n", + "
\n", + "

df2a

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
hire_date
employee
Lisa2004
Bob2008
Jake2012
Sue2014
\n", + "
\n", + "
\n", + "
\n", + "

pd.merge(df1a, df2a, left_index=True, right_index=True)

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
grouphire_date
employee
LisaEngineering2004
BobAccounting2008
JakeEngineering2012
SueHR2014
\n", + "
\n", + "
" + ], + "text/plain": [ + "df1a\n", + " group\n", + "employee \n", + "Bob Accounting\n", + "Jake Engineering\n", + "Lisa Engineering\n", + "Sue HR\n", + "\n", + "df2a\n", + " hire_date\n", + "employee \n", + "Lisa 2004\n", + "Bob 2008\n", + "Jake 2012\n", + "Sue 2014\n", + "\n", + "pd.merge(df1a, df2a, left_index=True, right_index=True)\n", + " group hire_date\n", + "employee \n", + "Lisa Engineering 2004\n", + "Bob Accounting 2008\n", + "Jake Engineering 2012\n", + "Sue HR 2014" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "display('df1a', 'df2a',\n", + " \"pd.merge(df1a, df2a, left_index=True, right_index=True)\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For convenience, ``DataFrame``s implement the ``join()`` method, which performs a merge that defaults to joining on indices:" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "

df1a

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
group
employee
BobAccounting
JakeEngineering
LisaEngineering
SueHR
\n", + "
\n", + "
\n", + "
\n", + "

df2a

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
hire_date
employee
Lisa2004
Bob2008
Jake2012
Sue2014
\n", + "
\n", + "
\n", + "
\n", + "

df1a.join(df2a)

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
grouphire_date
employee
BobAccounting2008
JakeEngineering2012
LisaEngineering2004
SueHR2014
\n", + "
\n", + "
" + ], + "text/plain": [ + "df1a\n", + " group\n", + "employee \n", + "Bob Accounting\n", + "Jake Engineering\n", + "Lisa Engineering\n", + "Sue HR\n", + "\n", + "df2a\n", + " hire_date\n", + "employee \n", + "Lisa 2004\n", + "Bob 2008\n", + "Jake 2012\n", + "Sue 2014\n", + "\n", + "df1a.join(df2a)\n", + " group hire_date\n", + "employee \n", + "Bob Accounting 2008\n", + "Jake Engineering 2012\n", + "Lisa Engineering 2004\n", + "Sue HR 2014" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "display('df1a', 'df2a', 'df1a.join(df2a)')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If you'd like to mix indices and columns, you can combine ``left_index`` with ``right_on`` or ``left_on`` with ``right_index`` to get the desired behavior:" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "

df1a

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
group
employee
BobAccounting
JakeEngineering
LisaEngineering
SueHR
\n", + "
\n", + "
\n", + "
\n", + "

df3

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
namesalary
0Bob70000
1Jake80000
2Lisa120000
3Sue90000
\n", + "
\n", + "
\n", + "
\n", + "

pd.merge(df1a, df3, left_index=True, right_on='name')

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
groupnamesalary
0AccountingBob70000
1EngineeringJake80000
2EngineeringLisa120000
3HRSue90000
\n", + "
\n", + "
" + ], + "text/plain": [ + "df1a\n", + " group\n", + "employee \n", + "Bob Accounting\n", + "Jake Engineering\n", + "Lisa Engineering\n", + "Sue HR\n", + "\n", + "df3\n", + " name salary\n", + "0 Bob 70000\n", + "1 Jake 80000\n", + "2 Lisa 120000\n", + "3 Sue 90000\n", + "\n", + "pd.merge(df1a, df3, left_index=True, right_on='name')\n", + " group name salary\n", + "0 Accounting Bob 70000\n", + "1 Engineering Jake 80000\n", + "2 Engineering Lisa 120000\n", + "3 HR Sue 90000" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "display('df1a', 'df3', \"pd.merge(df1a, df3, left_index=True, right_on='name')\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "All of these options also work with multiple indices and/or multiple columns; the interface for this behavior is very intuitive.\n", + "For more information on this, see the [\"Merge, Join, and Concatenate\" section](http://pandas.pydata.org/pandas-docs/stable/merging.html) of the Pandas documentation." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Specifying Set Arithmetic for Joins" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In all the preceding examples we have glossed over one important consideration in performing a join: the type of set arithmetic used in the join.\n", + "This comes up when a value appears in one key column but not the other. Consider this example:" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "

df6

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
namefood
0Peterfish
1Paulbeans
2Marybread
\n", + "
\n", + "
\n", + "
\n", + "

df7

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
namedrink
0Marywine
1Josephbeer
\n", + "
\n", + "
\n", + "
\n", + "

pd.merge(df6, df7)

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
namefooddrink
0Marybreadwine
\n", + "
\n", + "
" + ], + "text/plain": [ + "df6\n", + " name food\n", + "0 Peter fish\n", + "1 Paul beans\n", + "2 Mary bread\n", + "\n", + "df7\n", + " name drink\n", + "0 Mary wine\n", + "1 Joseph beer\n", + "\n", + "pd.merge(df6, df7)\n", + " name food drink\n", + "0 Mary bread wine" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df6 = pd.DataFrame({'name': ['Peter', 'Paul', 'Mary'],\n", + " 'food': ['fish', 'beans', 'bread']},\n", + " columns=['name', 'food'])\n", + "df7 = pd.DataFrame({'name': ['Mary', 'Joseph'],\n", + " 'drink': ['wine', 'beer']},\n", + " columns=['name', 'drink'])\n", + "display('df6', 'df7', 'pd.merge(df6, df7)')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here we have merged two datasets that have only a single \"name\" entry in common: Mary.\n", + "By default, the result contains the *intersection* of the two sets of inputs; this is what is known as an *inner join*.\n", + "We can specify this explicitly using the ``how`` keyword, which defaults to ``\"inner\"``:" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
namefooddrink
0Marybreadwine
\n", + "
" + ], + "text/plain": [ + " name food drink\n", + "0 Mary bread wine" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pd.merge(df6, df7, how='inner')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Other options for the ``how`` keyword are ``'outer'``, ``'left'``, and ``'right'``.\n", + "An *outer join* returns a join over the union of the input columns, and fills in all missing values with NAs:" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "

df6

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
namefood
0Peterfish
1Paulbeans
2Marybread
\n", + "
\n", + "
\n", + "
\n", + "

df7

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
namedrink
0Marywine
1Josephbeer
\n", + "
\n", + "
\n", + "
\n", + "

pd.merge(df6, df7, how='outer')

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
namefooddrink
0PeterfishNaN
1PaulbeansNaN
2Marybreadwine
3JosephNaNbeer
\n", + "
\n", + "
" + ], + "text/plain": [ + "df6\n", + " name food\n", + "0 Peter fish\n", + "1 Paul beans\n", + "2 Mary bread\n", + "\n", + "df7\n", + " name drink\n", + "0 Mary wine\n", + "1 Joseph beer\n", + "\n", + "pd.merge(df6, df7, how='outer')\n", + " name food drink\n", + "0 Peter fish NaN\n", + "1 Paul beans NaN\n", + "2 Mary bread wine\n", + "3 Joseph NaN beer" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "display('df6', 'df7', \"pd.merge(df6, df7, how='outer')\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The *left join* and *right join* return joins over the left entries and right entries, respectively.\n", + "For example:" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "

df6

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
namefood
0Peterfish
1Paulbeans
2Marybread
\n", + "
\n", + "
\n", + "
\n", + "

df7

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
namedrink
0Marywine
1Josephbeer
\n", + "
\n", + "
\n", + "
\n", + "

pd.merge(df6, df7, how='left')

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
namefooddrink
0PeterfishNaN
1PaulbeansNaN
2Marybreadwine
\n", + "
\n", + "
" + ], + "text/plain": [ + "df6\n", + " name food\n", + "0 Peter fish\n", + "1 Paul beans\n", + "2 Mary bread\n", + "\n", + "df7\n", + " name drink\n", + "0 Mary wine\n", + "1 Joseph beer\n", + "\n", + "pd.merge(df6, df7, how='left')\n", + " name food drink\n", + "0 Peter fish NaN\n", + "1 Paul beans NaN\n", + "2 Mary bread wine" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "display('df6', 'df7', \"pd.merge(df6, df7, how='left')\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The output rows now correspond to the entries in the left input. Using\n", + "``how='right'`` works in a similar manner.\n", + "\n", + "All of these options can be applied straightforwardly to any of the preceding join types." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Overlapping Column Names: The ``suffixes`` Keyword" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Finally, you may end up in a case where your two input ``DataFrame``s have conflicting column names.\n", + "Consider this example:" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "

df8

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
namerank
0Bob1
1Jake2
2Lisa3
3Sue4
\n", + "
\n", + "
\n", + "
\n", + "

df9

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
namerank
0Bob3
1Jake1
2Lisa4
3Sue2
\n", + "
\n", + "
\n", + "
\n", + "

pd.merge(df8, df9, on=\"name\")

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
namerank_xrank_y
0Bob13
1Jake21
2Lisa34
3Sue42
\n", + "
\n", + "
" + ], + "text/plain": [ + "df8\n", + " name rank\n", + "0 Bob 1\n", + "1 Jake 2\n", + "2 Lisa 3\n", + "3 Sue 4\n", + "\n", + "df9\n", + " name rank\n", + "0 Bob 3\n", + "1 Jake 1\n", + "2 Lisa 4\n", + "3 Sue 2\n", + "\n", + "pd.merge(df8, df9, on=\"name\")\n", + " name rank_x rank_y\n", + "0 Bob 1 3\n", + "1 Jake 2 1\n", + "2 Lisa 3 4\n", + "3 Sue 4 2" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df8 = pd.DataFrame({'name': ['Bob', 'Jake', 'Lisa', 'Sue'],\n", + " 'rank': [1, 2, 3, 4]})\n", + "df9 = pd.DataFrame({'name': ['Bob', 'Jake', 'Lisa', 'Sue'],\n", + " 'rank': [3, 1, 4, 2]})\n", + "display('df8', 'df9', 'pd.merge(df8, df9, on=\"name\")')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Because the output would have two conflicting column names, the merge function automatically appends a suffix ``_x`` or ``_y`` to make the output columns unique.\n", + "If these defaults are inappropriate, it is possible to specify a custom suffix using the ``suffixes`` keyword:" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "

df8

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
namerank
0Bob1
1Jake2
2Lisa3
3Sue4
\n", + "
\n", + "
\n", + "
\n", + "

df9

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
namerank
0Bob3
1Jake1
2Lisa4
3Sue2
\n", + "
\n", + "
\n", + "
\n", + "

pd.merge(df8, df9, on=\"name\", suffixes=[\"_L\", \"_R\"])

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
namerank_Lrank_R
0Bob13
1Jake21
2Lisa34
3Sue42
\n", + "
\n", + "
" + ], + "text/plain": [ + "df8\n", + " name rank\n", + "0 Bob 1\n", + "1 Jake 2\n", + "2 Lisa 3\n", + "3 Sue 4\n", + "\n", + "df9\n", + " name rank\n", + "0 Bob 3\n", + "1 Jake 1\n", + "2 Lisa 4\n", + "3 Sue 2\n", + "\n", + "pd.merge(df8, df9, on=\"name\", suffixes=[\"_L\", \"_R\"])\n", + " name rank_L rank_R\n", + "0 Bob 1 3\n", + "1 Jake 2 1\n", + "2 Lisa 3 4\n", + "3 Sue 4 2" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "display('df8', 'df9', 'pd.merge(df8, df9, on=\"name\", suffixes=[\"_L\", \"_R\"])')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "These suffixes work in any of the possible join patterns, and work also if there are multiple overlapping columns." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For more information on these patterns, see [Aggregation and Grouping](03.08-Aggregation-and-Grouping.ipynb) where we dive a bit deeper into relational algebra.\n", + "Also see the [Pandas \"Merge, Join and Concatenate\" documentation](http://pandas.pydata.org/pandas-docs/stable/merging.html) for further discussion of these topics." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Example: US States Data\n", + "\n", + "Merge and join operations come up most often when combining data from different sources.\n", + "Here we will consider an example of some data about US states and their populations.\n", + "The data files can be found at http://github.com/jakevdp/data-USstates/:" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Following are shell commands to download the data\n", + "# !curl -O https://raw.githubusercontent.com/jakevdp/data-USstates/master/state-population.csv\n", + "# !curl -O https://raw.githubusercontent.com/jakevdp/data-USstates/master/state-areas.csv\n", + "# !curl -O https://raw.githubusercontent.com/jakevdp/data-USstates/master/state-abbrevs.csv" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's take a look at the three datasets, using the Pandas ``read_csv()`` function:" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "

pop.head()

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
state/regionagesyearpopulation
0ALunder1820121117489.0
1ALtotal20124817528.0
2ALunder1820101130966.0
3ALtotal20104785570.0
4ALunder1820111125763.0
\n", + "
\n", + "
\n", + "
\n", + "

areas.head()

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
statearea (sq. mi)
0Alabama52423
1Alaska656425
2Arizona114006
3Arkansas53182
4California163707
\n", + "
\n", + "
\n", + "
\n", + "

abbrevs.head()

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
stateabbreviation
0AlabamaAL
1AlaskaAK
2ArizonaAZ
3ArkansasAR
4CaliforniaCA
\n", + "
\n", + "
" + ], + "text/plain": [ + "pop.head()\n", + " state/region ages year population\n", + "0 AL under18 2012 1117489.0\n", + "1 AL total 2012 4817528.0\n", + "2 AL under18 2010 1130966.0\n", + "3 AL total 2010 4785570.0\n", + "4 AL under18 2011 1125763.0\n", + "\n", + "areas.head()\n", + " state area (sq. mi)\n", + "0 Alabama 52423\n", + "1 Alaska 656425\n", + "2 Arizona 114006\n", + "3 Arkansas 53182\n", + "4 California 163707\n", + "\n", + "abbrevs.head()\n", + " state abbreviation\n", + "0 Alabama AL\n", + "1 Alaska AK\n", + "2 Arizona AZ\n", + "3 Arkansas AR\n", + "4 California CA" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pop = pd.read_csv('data/state-population.csv')\n", + "areas = pd.read_csv('data/state-areas.csv')\n", + "abbrevs = pd.read_csv('data/state-abbrevs.csv')\n", + "\n", + "display('pop.head()', 'areas.head()', 'abbrevs.head()')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Given this information, say we want to compute a relatively straightforward result: rank US states and territories by their 2010 population density.\n", + "We clearly have the data here to find this result, but we'll have to combine the datasets to find the result.\n", + "\n", + "We'll start with a many-to-one merge that will give us the full state name within the population ``DataFrame``.\n", + "We want to merge based on the ``state/region`` column of ``pop``, and the ``abbreviation`` column of ``abbrevs``.\n", + "We'll use ``how='outer'`` to make sure no data is thrown away due to mismatched labels." + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
state/regionagesyearpopulationstate
0ALunder1820121117489.0Alabama
1ALtotal20124817528.0Alabama
2ALunder1820101130966.0Alabama
3ALtotal20104785570.0Alabama
4ALunder1820111125763.0Alabama
\n", + "
" + ], + "text/plain": [ + " state/region ages year population state\n", + "0 AL under18 2012 1117489.0 Alabama\n", + "1 AL total 2012 4817528.0 Alabama\n", + "2 AL under18 2010 1130966.0 Alabama\n", + "3 AL total 2010 4785570.0 Alabama\n", + "4 AL under18 2011 1125763.0 Alabama" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "merged = pd.merge(pop, abbrevs, how='outer',\n", + " left_on='state/region', right_on='abbreviation')\n", + "merged = merged.drop('abbreviation', 1) # drop duplicate info\n", + "merged.head()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's double-check whether there were any mismatches here, which we can do by looking for rows with nulls:" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "state/region False\n", + "ages False\n", + "year False\n", + "population True\n", + "state True\n", + "dtype: bool" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "merged.isnull().any()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Some of the ``population`` info is null; let's figure out which these are!" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
state/regionagesyearpopulationstate
2448PRunder181990NaNNaN
2449PRtotal1990NaNNaN
2450PRtotal1991NaNNaN
2451PRunder181991NaNNaN
2452PRtotal1993NaNNaN
\n", + "
" + ], + "text/plain": [ + " state/region ages year population state\n", + "2448 PR under18 1990 NaN NaN\n", + "2449 PR total 1990 NaN NaN\n", + "2450 PR total 1991 NaN NaN\n", + "2451 PR under18 1991 NaN NaN\n", + "2452 PR total 1993 NaN NaN" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "merged[merged['population'].isnull()].head()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "It appears that all the null population values are from Puerto Rico prior to the year 2000; this is likely due to this data not being available from the original source.\n", + "\n", + "More importantly, we see also that some of the new ``state`` entries are also null, which means that there was no corresponding entry in the ``abbrevs`` key!\n", + "Let's figure out which regions lack this match:" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array(['PR', 'USA'], dtype=object)" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "merged.loc[merged['state'].isnull(), 'state/region'].unique()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can quickly infer the issue: our population data includes entries for Puerto Rico (PR) and the United States as a whole (USA), while these entries do not appear in the state abbreviation key.\n", + "We can fix these quickly by filling in appropriate entries:" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "state/region False\n", + "ages False\n", + "year False\n", + "population True\n", + "state False\n", + "dtype: bool" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "merged.loc[merged['state/region'] == 'PR', 'state'] = 'Puerto Rico'\n", + "merged.loc[merged['state/region'] == 'USA', 'state'] = 'United States'\n", + "merged.isnull().any()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "No more nulls in the ``state`` column: we're all set!\n", + "\n", + "Now we can merge the result with the area data using a similar procedure.\n", + "Examining our results, we will want to join on the ``state`` column in both:" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
state/regionagesyearpopulationstatearea (sq. mi)
0ALunder1820121117489.0Alabama52423.0
1ALtotal20124817528.0Alabama52423.0
2ALunder1820101130966.0Alabama52423.0
3ALtotal20104785570.0Alabama52423.0
4ALunder1820111125763.0Alabama52423.0
\n", + "
" + ], + "text/plain": [ + " state/region ages year population state area (sq. mi)\n", + "0 AL under18 2012 1117489.0 Alabama 52423.0\n", + "1 AL total 2012 4817528.0 Alabama 52423.0\n", + "2 AL under18 2010 1130966.0 Alabama 52423.0\n", + "3 AL total 2010 4785570.0 Alabama 52423.0\n", + "4 AL under18 2011 1125763.0 Alabama 52423.0" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "final = pd.merge(merged, areas, on='state', how='left')\n", + "final.head()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Again, let's check for nulls to see if there were any mismatches:" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "state/region False\n", + "ages False\n", + "year False\n", + "population True\n", + "state False\n", + "area (sq. mi) True\n", + "dtype: bool" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "final.isnull().any()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "There are nulls in the ``area`` column; we can take a look to see which regions were ignored here:" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array(['United States'], dtype=object)" + ] + }, + "execution_count": 28, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "final['state'][final['area (sq. mi)'].isnull()].unique()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We see that our ``areas`` ``DataFrame`` does not contain the area of the United States as a whole.\n", + "We could insert the appropriate value (using the sum of all state areas, for instance), but in this case we'll just drop the null values because the population density of the entire United States is not relevant to our current discussion:" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
state/regionagesyearpopulationstatearea (sq. mi)
0ALunder1820121117489.0Alabama52423.0
1ALtotal20124817528.0Alabama52423.0
2ALunder1820101130966.0Alabama52423.0
3ALtotal20104785570.0Alabama52423.0
4ALunder1820111125763.0Alabama52423.0
\n", + "
" + ], + "text/plain": [ + " state/region ages year population state area (sq. mi)\n", + "0 AL under18 2012 1117489.0 Alabama 52423.0\n", + "1 AL total 2012 4817528.0 Alabama 52423.0\n", + "2 AL under18 2010 1130966.0 Alabama 52423.0\n", + "3 AL total 2010 4785570.0 Alabama 52423.0\n", + "4 AL under18 2011 1125763.0 Alabama 52423.0" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "final.dropna(inplace=True)\n", + "final.head()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we have all the data we need. To answer the question of interest, let's first select the portion of the data corresponding with the year 2000, and the total population.\n", + "We'll use the ``query()`` function to do this quickly (this requires the ``numexpr`` package to be installed; see [High-Performance Pandas: ``eval()`` and ``query()``](03.12-Performance-Eval-and-Query.ipynb)):" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
state/regionagesyearpopulationstatearea (sq. mi)
3ALtotal20104785570.0Alabama52423.0
91AKtotal2010713868.0Alaska656425.0
101AZtotal20106408790.0Arizona114006.0
189ARtotal20102922280.0Arkansas53182.0
197CAtotal201037333601.0California163707.0
\n", + "
" + ], + "text/plain": [ + " state/region ages year population state area (sq. mi)\n", + "3 AL total 2010 4785570.0 Alabama 52423.0\n", + "91 AK total 2010 713868.0 Alaska 656425.0\n", + "101 AZ total 2010 6408790.0 Arizona 114006.0\n", + "189 AR total 2010 2922280.0 Arkansas 53182.0\n", + "197 CA total 2010 37333601.0 California 163707.0" + ] + }, + "execution_count": 30, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data2010 = final.query(\"year == 2010 & ages == 'total'\")\n", + "data2010.head()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now let's compute the population density and display it in order.\n", + "We'll start by re-indexing our data on the state, and then compute the result:" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "data2010.set_index('state', inplace=True)\n", + "density = data2010['population'] / data2010['area (sq. mi)']" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "state\n", + "District of Columbia 8898.897059\n", + "Puerto Rico 1058.665149\n", + "New Jersey 1009.253268\n", + "Rhode Island 681.339159\n", + "Connecticut 645.600649\n", + "dtype: float64" + ] + }, + "execution_count": 32, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "density.sort_values(ascending=False, inplace=True)\n", + "density.head()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The result is a ranking of US states plus Washington, DC, and Puerto Rico in order of their 2010 population density, in residents per square mile.\n", + "We can see that by far the densest region in this dataset is Washington, DC (i.e., the District of Columbia); among states, the densest is New Jersey.\n", + "\n", + "We can also check the end of the list:" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "state\n", + "South Dakota 10.583512\n", + "North Dakota 9.537565\n", + "Montana 6.736171\n", + "Wyoming 5.768079\n", + "Alaska 1.087509\n", + "dtype: float64" + ] + }, + "execution_count": 33, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "density.tail()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We see that the least dense state, by far, is Alaska, averaging slightly over one resident per square mile.\n", + "\n", + "This type of messy data merging is a common task when trying to answer questions using real-world data sources.\n", + "I hope that this example has given you an idea of the ways you can combine tools we've covered in order to gain insight from your data!" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "< [Combining Datasets: Concat and Append](03.06-Concat-And-Append.ipynb) | [Contents](Index.ipynb) | [Aggregation and Grouping](03.08-Aggregation-and-Grouping.ipynb) >" + ] + } + ], + "metadata": { + "anaconda-cloud": {}, + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.4.3" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/pandas/03.08-Aggregation-and-Grouping.ipynb b/pandas/03.08-Aggregation-and-Grouping.ipynb new file mode 100644 index 0000000..27a4d80 --- /dev/null +++ b/pandas/03.08-Aggregation-and-Grouping.ipynb @@ -0,0 +1,2657 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "\n", + "*This notebook contains an excerpt from the [Python Data Science Handbook](http://shop.oreilly.com/product/0636920034919.do) by Jake VanderPlas; the content is available [on GitHub](https://github.com/jakevdp/PythonDataScienceHandbook).*\n", + "\n", + "*The text is released under the [CC-BY-NC-ND license](https://creativecommons.org/licenses/by-nc-nd/3.0/us/legalcode), and code is released under the [MIT license](https://opensource.org/licenses/MIT). If you find this content useful, please consider supporting the work by [buying the book](http://shop.oreilly.com/product/0636920034919.do)!*\n", + "\n", + "*No changes were made to the contents of this notebook from the original.*" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "< [Combining Datasets: Merge and Join](03.07-Merge-and-Join.ipynb) | [Contents](Index.ipynb) | [Pivot Tables](03.09-Pivot-Tables.ipynb) >" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Aggregation and Grouping" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "An essential piece of analysis of large data is efficient summarization: computing aggregations like ``sum()``, ``mean()``, ``median()``, ``min()``, and ``max()``, in which a single number gives insight into the nature of a potentially large dataset.\n", + "In this section, we'll explore aggregations in Pandas, from simple operations akin to what we've seen on NumPy arrays, to more sophisticated operations based on the concept of a ``groupby``." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For convenience, we'll use the same ``display`` magic function that we've seen in previous sections:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "\n", + "class display(object):\n", + " \"\"\"Display HTML representation of multiple objects\"\"\"\n", + " template = \"\"\"
\n", + "

{0}

{1}\n", + "
\"\"\"\n", + " def __init__(self, *args):\n", + " self.args = args\n", + " \n", + " def _repr_html_(self):\n", + " return '\\n'.join(self.template.format(a, eval(a)._repr_html_())\n", + " for a in self.args)\n", + " \n", + " def __repr__(self):\n", + " return '\\n\\n'.join(a + '\\n' + repr(eval(a))\n", + " for a in self.args)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Planets Data\n", + "\n", + "Here we will use the Planets dataset, available via the [Seaborn package](http://seaborn.pydata.org/) (see [Visualization With Seaborn](04.14-Visualization-With-Seaborn.ipynb)).\n", + "It gives information on planets that astronomers have discovered around other stars (known as *extrasolar planets* or *exoplanets* for short). It can be downloaded with a simple Seaborn command:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(1035, 6)" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import seaborn as sns\n", + "planets = sns.load_dataset('planets')\n", + "planets.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
methodnumberorbital_periodmassdistanceyear
0Radial Velocity1269.3007.1077.402006
1Radial Velocity1874.7742.2156.952008
2Radial Velocity1763.0002.6019.842011
3Radial Velocity1326.03019.40110.622007
4Radial Velocity1516.22010.50119.472009
\n", + "
" + ], + "text/plain": [ + " method number orbital_period mass distance year\n", + "0 Radial Velocity 1 269.300 7.10 77.40 2006\n", + "1 Radial Velocity 1 874.774 2.21 56.95 2008\n", + "2 Radial Velocity 1 763.000 2.60 19.84 2011\n", + "3 Radial Velocity 1 326.030 19.40 110.62 2007\n", + "4 Radial Velocity 1 516.220 10.50 119.47 2009" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "planets.head()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This has some details on the 1,000+ extrasolar planets discovered up to 2014." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Simple Aggregation in Pandas" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Earlier, we explored some of the data aggregations available for NumPy arrays ([\"Aggregations: Min, Max, and Everything In Between\"](02.04-Computation-on-arrays-aggregates.ipynb)).\n", + "As with a one-dimensional NumPy array, for a Pandas ``Series`` the aggregates return a single value:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "0 0.374540\n", + "1 0.950714\n", + "2 0.731994\n", + "3 0.598658\n", + "4 0.156019\n", + "dtype: float64" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "rng = np.random.RandomState(42)\n", + "ser = pd.Series(rng.rand(5))\n", + "ser" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "2.8119254917081569" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "ser.sum()" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "0.56238509834163142" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "ser.mean()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For a ``DataFrame``, by default the aggregates return results within each column:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
AB
00.1559950.020584
10.0580840.969910
20.8661760.832443
30.6011150.212339
40.7080730.181825
\n", + "
" + ], + "text/plain": [ + " A B\n", + "0 0.155995 0.020584\n", + "1 0.058084 0.969910\n", + "2 0.866176 0.832443\n", + "3 0.601115 0.212339\n", + "4 0.708073 0.181825" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df = pd.DataFrame({'A': rng.rand(5),\n", + " 'B': rng.rand(5)})\n", + "df" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "A 0.477888\n", + "B 0.443420\n", + "dtype: float64" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.mean()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "By specifying the ``axis`` argument, you can instead aggregate within each row:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "0 0.088290\n", + "1 0.513997\n", + "2 0.849309\n", + "3 0.406727\n", + "4 0.444949\n", + "dtype: float64" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.mean(axis='columns')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Pandas ``Series`` and ``DataFrame``s include all of the common aggregates mentioned in [Aggregations: Min, Max, and Everything In Between](02.04-Computation-on-arrays-aggregates.ipynb); in addition, there is a convenience method ``describe()`` that computes several common aggregates for each column and returns the result.\n", + "Let's use this on the Planets data, for now dropping rows with missing values:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
numberorbital_periodmassdistanceyear
count498.00000498.000000498.000000498.000000498.000000
mean1.73494835.7786712.50932052.0682132007.377510
std1.175721469.1282593.63627446.5960414.167284
min1.000001.3283000.0036001.3500001989.000000
25%1.0000038.2722500.21250024.4975002005.000000
50%1.00000357.0000001.24500039.9400002009.000000
75%2.00000999.6000002.86750059.3325002011.000000
max6.0000017337.50000025.000000354.0000002014.000000
\n", + "
" + ], + "text/plain": [ + " number orbital_period mass distance year\n", + "count 498.00000 498.000000 498.000000 498.000000 498.000000\n", + "mean 1.73494 835.778671 2.509320 52.068213 2007.377510\n", + "std 1.17572 1469.128259 3.636274 46.596041 4.167284\n", + "min 1.00000 1.328300 0.003600 1.350000 1989.000000\n", + "25% 1.00000 38.272250 0.212500 24.497500 2005.000000\n", + "50% 1.00000 357.000000 1.245000 39.940000 2009.000000\n", + "75% 2.00000 999.600000 2.867500 59.332500 2011.000000\n", + "max 6.00000 17337.500000 25.000000 354.000000 2014.000000" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "planets.dropna().describe()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This can be a useful way to begin understanding the overall properties of a dataset.\n", + "For example, we see in the ``year`` column that although exoplanets were discovered as far back as 1989, half of all known expolanets were not discovered until 2010 or after.\n", + "This is largely thanks to the *Kepler* mission, which is a space-based telescope specifically designed for finding eclipsing planets around other stars." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The following table summarizes some other built-in Pandas aggregations:\n", + "\n", + "| Aggregation | Description |\n", + "|--------------------------|---------------------------------|\n", + "| ``count()`` | Total number of items |\n", + "| ``first()``, ``last()`` | First and last item |\n", + "| ``mean()``, ``median()`` | Mean and median |\n", + "| ``min()``, ``max()`` | Minimum and maximum |\n", + "| ``std()``, ``var()`` | Standard deviation and variance |\n", + "| ``mad()`` | Mean absolute deviation |\n", + "| ``prod()`` | Product of all items |\n", + "| ``sum()`` | Sum of all items |\n", + "\n", + "These are all methods of ``DataFrame`` and ``Series`` objects." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To go deeper into the data, however, simple aggregates are often not enough.\n", + "The next level of data summarization is the ``groupby`` operation, which allows you to quickly and efficiently compute aggregates on subsets of data." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## GroupBy: Split, Apply, Combine\n", + "\n", + "Simple aggregations can give you a flavor of your dataset, but often we would prefer to aggregate conditionally on some label or index: this is implemented in the so-called ``groupby`` operation.\n", + "The name \"group by\" comes from a command in the SQL database language, but it is perhaps more illuminative to think of it in the terms first coined by Hadley Wickham of Rstats fame: *split, apply, combine*." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Split, apply, combine\n", + "\n", + "A canonical example of this split-apply-combine operation, where the \"apply\" is a summation aggregation, is illustrated in this figure:" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "![](figures/03.08-split-apply-combine.png)\n", + "[figure source in Appendix](06.00-Figure-Code.ipynb#Split-Apply-Combine)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This makes clear what the ``groupby`` accomplishes:\n", + "\n", + "- The *split* step involves breaking up and grouping a ``DataFrame`` depending on the value of the specified key.\n", + "- The *apply* step involves computing some function, usually an aggregate, transformation, or filtering, within the individual groups.\n", + "- The *combine* step merges the results of these operations into an output array.\n", + "\n", + "While this could certainly be done manually using some combination of the masking, aggregation, and merging commands covered earlier, an important realization is that *the intermediate splits do not need to be explicitly instantiated*. Rather, the ``GroupBy`` can (often) do this in a single pass over the data, updating the sum, mean, count, min, or other aggregate for each group along the way.\n", + "The power of the ``GroupBy`` is that it abstracts away these steps: the user need not think about *how* the computation is done under the hood, but rather thinks about the *operation as a whole*.\n", + "\n", + "As a concrete example, let's take a look at using Pandas for the computation shown in this diagram.\n", + "We'll start by creating the input ``DataFrame``:" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
keydata
0A0
1B1
2C2
3A3
4B4
5C5
\n", + "
" + ], + "text/plain": [ + " key data\n", + "0 A 0\n", + "1 B 1\n", + "2 C 2\n", + "3 A 3\n", + "4 B 4\n", + "5 C 5" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df = pd.DataFrame({'key': ['A', 'B', 'C', 'A', 'B', 'C'],\n", + " 'data': range(6)}, columns=['key', 'data'])\n", + "df" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The most basic split-apply-combine operation can be computed with the ``groupby()`` method of ``DataFrame``s, passing the name of the desired key column:" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.groupby('key')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Notice that what is returned is not a set of ``DataFrame``s, but a ``DataFrameGroupBy`` object.\n", + "This object is where the magic is: you can think of it as a special view of the ``DataFrame``, which is poised to dig into the groups but does no actual computation until the aggregation is applied.\n", + "This \"lazy evaluation\" approach means that common aggregates can be implemented very efficiently in a way that is almost transparent to the user.\n", + "\n", + "To produce a result, we can apply an aggregate to this ``DataFrameGroupBy`` object, which will perform the appropriate apply/combine steps to produce the desired result:" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
data
key
A3
B5
C7
\n", + "
" + ], + "text/plain": [ + " data\n", + "key \n", + "A 3\n", + "B 5\n", + "C 7" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.groupby('key').sum()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The ``sum()`` method is just one possibility here; you can apply virtually any common Pandas or NumPy aggregation function, as well as virtually any valid ``DataFrame`` operation, as we will see in the following discussion." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### The GroupBy object\n", + "\n", + "The ``GroupBy`` object is a very flexible abstraction.\n", + "In many ways, you can simply treat it as if it's a collection of ``DataFrame``s, and it does the difficult things under the hood. Let's see some examples using the Planets data.\n", + "\n", + "Perhaps the most important operations made available by a ``GroupBy`` are *aggregate*, *filter*, *transform*, and *apply*.\n", + "We'll discuss each of these more fully in [\"Aggregate, Filter, Transform, Apply\"](#Aggregate,-Filter,-Transform,-Apply), but before that let's introduce some of the other functionality that can be used with the basic ``GroupBy`` operation." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Column indexing\n", + "\n", + "The ``GroupBy`` object supports column indexing in the same way as the ``DataFrame``, and returns a modified ``GroupBy`` object.\n", + "For example:" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "planets.groupby('method')" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "planets.groupby('method')['orbital_period']" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here we've selected a particular ``Series`` group from the original ``DataFrame`` group by reference to its column name.\n", + "As with the ``GroupBy`` object, no computation is done until we call some aggregate on the object:" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "method\n", + "Astrometry 631.180000\n", + "Eclipse Timing Variations 4343.500000\n", + "Imaging 27500.000000\n", + "Microlensing 3300.000000\n", + "Orbital Brightness Modulation 0.342887\n", + "Pulsar Timing 66.541900\n", + "Pulsation Timing Variations 1170.000000\n", + "Radial Velocity 360.200000\n", + "Transit 5.714932\n", + "Transit Timing Variations 57.011000\n", + "Name: orbital_period, dtype: float64" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "planets.groupby('method')['orbital_period'].median()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This gives an idea of the general scale of orbital periods (in days) that each method is sensitive to." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Iteration over groups\n", + "\n", + "The ``GroupBy`` object supports direct iteration over the groups, returning each group as a ``Series`` or ``DataFrame``:" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Astrometry shape=(2, 6)\n", + "Eclipse Timing Variations shape=(9, 6)\n", + "Imaging shape=(38, 6)\n", + "Microlensing shape=(23, 6)\n", + "Orbital Brightness Modulation shape=(3, 6)\n", + "Pulsar Timing shape=(5, 6)\n", + "Pulsation Timing Variations shape=(1, 6)\n", + "Radial Velocity shape=(553, 6)\n", + "Transit shape=(397, 6)\n", + "Transit Timing Variations shape=(4, 6)\n" + ] + } + ], + "source": [ + "for (method, group) in planets.groupby('method'):\n", + " print(\"{0:30s} shape={1}\".format(method, group.shape))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This can be useful for doing certain things manually, though it is often much faster to use the built-in ``apply`` functionality, which we will discuss momentarily." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Dispatch methods\n", + "\n", + "Through some Python class magic, any method not explicitly implemented by the ``GroupBy`` object will be passed through and called on the groups, whether they are ``DataFrame`` or ``Series`` objects.\n", + "For example, you can use the ``describe()`` method of ``DataFrame``s to perform a set of aggregations that describe each group in the data:" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
countmeanstdmin25%50%75%max
method
Astrometry2.02011.5000002.1213202010.02010.752011.52012.252013.0
Eclipse Timing Variations9.02010.0000001.4142142008.02009.002010.02011.002012.0
Imaging38.02009.1315792.7819012004.02008.002009.02011.002013.0
Microlensing23.02009.7826092.8596972004.02008.002010.02012.002013.0
Orbital Brightness Modulation3.02011.6666671.1547012011.02011.002011.02012.002013.0
Pulsar Timing5.01998.4000008.3845101992.01992.001994.02003.002011.0
Pulsation Timing Variations1.02007.000000NaN2007.02007.002007.02007.002007.0
Radial Velocity553.02007.5189874.2490521989.02005.002009.02011.002014.0
Transit397.02011.2367762.0778672002.02010.002012.02013.002014.0
Transit Timing Variations4.02012.5000001.2909942011.02011.752012.52013.252014.0
\n", + "
" + ], + "text/plain": [ + " count mean std min 25% \\\n", + "method \n", + "Astrometry 2.0 2011.500000 2.121320 2010.0 2010.75 \n", + "Eclipse Timing Variations 9.0 2010.000000 1.414214 2008.0 2009.00 \n", + "Imaging 38.0 2009.131579 2.781901 2004.0 2008.00 \n", + "Microlensing 23.0 2009.782609 2.859697 2004.0 2008.00 \n", + "Orbital Brightness Modulation 3.0 2011.666667 1.154701 2011.0 2011.00 \n", + "Pulsar Timing 5.0 1998.400000 8.384510 1992.0 1992.00 \n", + "Pulsation Timing Variations 1.0 2007.000000 NaN 2007.0 2007.00 \n", + "Radial Velocity 553.0 2007.518987 4.249052 1989.0 2005.00 \n", + "Transit 397.0 2011.236776 2.077867 2002.0 2010.00 \n", + "Transit Timing Variations 4.0 2012.500000 1.290994 2011.0 2011.75 \n", + "\n", + " 50% 75% max \n", + "method \n", + "Astrometry 2011.5 2012.25 2013.0 \n", + "Eclipse Timing Variations 2010.0 2011.00 2012.0 \n", + "Imaging 2009.0 2011.00 2013.0 \n", + "Microlensing 2010.0 2012.00 2013.0 \n", + "Orbital Brightness Modulation 2011.0 2012.00 2013.0 \n", + "Pulsar Timing 1994.0 2003.00 2011.0 \n", + "Pulsation Timing Variations 2007.0 2007.00 2007.0 \n", + "Radial Velocity 2009.0 2011.00 2014.0 \n", + "Transit 2012.0 2013.00 2014.0 \n", + "Transit Timing Variations 2012.5 2013.25 2014.0 " + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "planets.groupby('method')['year'].describe().unstack()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Looking at this table helps us to better understand the data: for example, the vast majority of planets have been discovered by the Radial Velocity and Transit methods, though the latter only became common (due to new, more accurate telescopes) in the last decade.\n", + "The newest methods seem to be Transit Timing Variation and Orbital Brightness Modulation, which were not used to discover a new planet until 2011.\n", + "\n", + "This is just one example of the utility of dispatch methods.\n", + "Notice that they are applied *to each individual group*, and the results are then combined within ``GroupBy`` and returned.\n", + "Again, any valid ``DataFrame``/``Series`` method can be used on the corresponding ``GroupBy`` object, which allows for some very flexible and powerful operations!" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Aggregate, filter, transform, apply\n", + "\n", + "The preceding discussion focused on aggregation for the combine operation, but there are more options available.\n", + "In particular, ``GroupBy`` objects have ``aggregate()``, ``filter()``, ``transform()``, and ``apply()`` methods that efficiently implement a variety of useful operations before combining the grouped data.\n", + "\n", + "For the purpose of the following subsections, we'll use this ``DataFrame``:" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
keydata1data2
0A05
1B10
2C23
3A33
4B47
5C59
\n", + "
" + ], + "text/plain": [ + " key data1 data2\n", + "0 A 0 5\n", + "1 B 1 0\n", + "2 C 2 3\n", + "3 A 3 3\n", + "4 B 4 7\n", + "5 C 5 9" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "rng = np.random.RandomState(0)\n", + "df = pd.DataFrame({'key': ['A', 'B', 'C', 'A', 'B', 'C'],\n", + " 'data1': range(6),\n", + " 'data2': rng.randint(0, 10, 6)},\n", + " columns = ['key', 'data1', 'data2'])\n", + "df" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Aggregation\n", + "\n", + "We're now familiar with ``GroupBy`` aggregations with ``sum()``, ``median()``, and the like, but the ``aggregate()`` method allows for even more flexibility.\n", + "It can take a string, a function, or a list thereof, and compute all the aggregates at once.\n", + "Here is a quick example combining all these:" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
data1data2
minmedianmaxminmedianmax
key
A01.5334.05
B12.5403.57
C23.5536.09
\n", + "
" + ], + "text/plain": [ + " data1 data2 \n", + " min median max min median max\n", + "key \n", + "A 0 1.5 3 3 4.0 5\n", + "B 1 2.5 4 0 3.5 7\n", + "C 2 3.5 5 3 6.0 9" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.groupby('key').aggregate(['min', np.median, max])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Another useful pattern is to pass a dictionary mapping column names to operations to be applied on that column:" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
data1data2
key
A05
B17
C29
\n", + "
" + ], + "text/plain": [ + " data1 data2\n", + "key \n", + "A 0 5\n", + "B 1 7\n", + "C 2 9" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.groupby('key').aggregate({'data1': 'min',\n", + " 'data2': 'max'})" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Filtering\n", + "\n", + "A filtering operation allows you to drop data based on the group properties.\n", + "For example, we might want to keep all groups in which the standard deviation is larger than some critical value:" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "

df

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
keydata1data2
0A05
1B10
2C23
3A33
4B47
5C59
\n", + "
\n", + "
\n", + "
\n", + "

df.groupby('key').std()

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
data1data2
key
A2.121321.414214
B2.121324.949747
C2.121324.242641
\n", + "
\n", + "
\n", + "
\n", + "

df.groupby('key').filter(filter_func)

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
keydata1data2
1B10
2C23
4B47
5C59
\n", + "
\n", + "
" + ], + "text/plain": [ + "df\n", + " key data1 data2\n", + "0 A 0 5\n", + "1 B 1 0\n", + "2 C 2 3\n", + "3 A 3 3\n", + "4 B 4 7\n", + "5 C 5 9\n", + "\n", + "df.groupby('key').std()\n", + " data1 data2\n", + "key \n", + "A 2.12132 1.414214\n", + "B 2.12132 4.949747\n", + "C 2.12132 4.242641\n", + "\n", + "df.groupby('key').filter(filter_func)\n", + " key data1 data2\n", + "1 B 1 0\n", + "2 C 2 3\n", + "4 B 4 7\n", + "5 C 5 9" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def filter_func(x):\n", + " return x['data2'].std() > 4\n", + "\n", + "display('df', \"df.groupby('key').std()\", \"df.groupby('key').filter(filter_func)\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The filter function should return a Boolean value specifying whether the group passes the filtering. Here because group A does not have a standard deviation greater than 4, it is dropped from the result." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Transformation\n", + "\n", + "While aggregation must return a reduced version of the data, transformation can return some transformed version of the full data to recombine.\n", + "For such a transformation, the output is the same shape as the input.\n", + "A common example is to center the data by subtracting the group-wise mean:" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
data1data2
0-1.51.0
1-1.5-3.5
2-1.5-3.0
31.5-1.0
41.53.5
51.53.0
\n", + "
" + ], + "text/plain": [ + " data1 data2\n", + "0 -1.5 1.0\n", + "1 -1.5 -3.5\n", + "2 -1.5 -3.0\n", + "3 1.5 -1.0\n", + "4 1.5 3.5\n", + "5 1.5 3.0" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.groupby('key').transform(lambda x: x - x.mean())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### The apply() method\n", + "\n", + "The ``apply()`` method lets you apply an arbitrary function to the group results.\n", + "The function should take a ``DataFrame``, and return either a Pandas object (e.g., ``DataFrame``, ``Series``) or a scalar; the combine operation will be tailored to the type of output returned.\n", + "\n", + "For example, here is an ``apply()`` that normalizes the first column by the sum of the second:" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "

df

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
keydata1data2
0A05
1B10
2C23
3A33
4B47
5C59
\n", + "
\n", + "
\n", + "
\n", + "

df.groupby('key').apply(norm_by_data2)

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
keydata1data2
0A0.0000005
1B0.1428570
2C0.1666673
3A0.3750003
4B0.5714297
5C0.4166679
\n", + "
\n", + "
" + ], + "text/plain": [ + "df\n", + " key data1 data2\n", + "0 A 0 5\n", + "1 B 1 0\n", + "2 C 2 3\n", + "3 A 3 3\n", + "4 B 4 7\n", + "5 C 5 9\n", + "\n", + "df.groupby('key').apply(norm_by_data2)\n", + " key data1 data2\n", + "0 A 0.000000 5\n", + "1 B 0.142857 0\n", + "2 C 0.166667 3\n", + "3 A 0.375000 3\n", + "4 B 0.571429 7\n", + "5 C 0.416667 9" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def norm_by_data2(x):\n", + " # x is a DataFrame of group values\n", + " x['data1'] /= x['data2'].sum()\n", + " return x\n", + "\n", + "display('df', \"df.groupby('key').apply(norm_by_data2)\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "``apply()`` within a ``GroupBy`` is quite flexible: the only criterion is that the function takes a ``DataFrame`` and returns a Pandas object or scalar; what you do in the middle is up to you!" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Specifying the split key\n", + "\n", + "In the simple examples presented before, we split the ``DataFrame`` on a single column name.\n", + "This is just one of many options by which the groups can be defined, and we'll go through some other options for group specification here." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### A list, array, series, or index providing the grouping keys\n", + "\n", + "The key can be any series or list with a length matching that of the ``DataFrame``. For example:" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "

df

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
keydata1data2
0A05
1B10
2C23
3A33
4B47
5C59
\n", + "
\n", + "
\n", + "
\n", + "

df.groupby(L).sum()

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
data1data2
0717
143
247
\n", + "
\n", + "
" + ], + "text/plain": [ + "df\n", + " key data1 data2\n", + "0 A 0 5\n", + "1 B 1 0\n", + "2 C 2 3\n", + "3 A 3 3\n", + "4 B 4 7\n", + "5 C 5 9\n", + "\n", + "df.groupby(L).sum()\n", + " data1 data2\n", + "0 7 17\n", + "1 4 3\n", + "2 4 7" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "L = [0, 1, 0, 1, 2, 0]\n", + "display('df', 'df.groupby(L).sum()')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Of course, this means there's another, more verbose way of accomplishing the ``df.groupby('key')`` from before:" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "

df

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
keydata1data2
0A05
1B10
2C23
3A33
4B47
5C59
\n", + "
\n", + "
\n", + "
\n", + "

df.groupby(df['key']).sum()

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
data1data2
key
A38
B57
C712
\n", + "
\n", + "
" + ], + "text/plain": [ + "df\n", + " key data1 data2\n", + "0 A 0 5\n", + "1 B 1 0\n", + "2 C 2 3\n", + "3 A 3 3\n", + "4 B 4 7\n", + "5 C 5 9\n", + "\n", + "df.groupby(df['key']).sum()\n", + " data1 data2\n", + "key \n", + "A 3 8\n", + "B 5 7\n", + "C 7 12" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "display('df', \"df.groupby(df['key']).sum()\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### A dictionary or series mapping index to group\n", + "\n", + "Another method is to provide a dictionary that maps index values to the group keys:" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "

df2

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
data1data2
key
A05
B10
C23
A33
B47
C59
\n", + "
\n", + "
\n", + "
\n", + "

df2.groupby(mapping).sum()

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
data1data2
consonant1219
vowel38
\n", + "
\n", + "
" + ], + "text/plain": [ + "df2\n", + " data1 data2\n", + "key \n", + "A 0 5\n", + "B 1 0\n", + "C 2 3\n", + "A 3 3\n", + "B 4 7\n", + "C 5 9\n", + "\n", + "df2.groupby(mapping).sum()\n", + " data1 data2\n", + "consonant 12 19\n", + "vowel 3 8" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df2 = df.set_index('key')\n", + "mapping = {'A': 'vowel', 'B': 'consonant', 'C': 'consonant'}\n", + "display('df2', 'df2.groupby(mapping).sum()')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Any Python function\n", + "\n", + "Similar to mapping, you can pass any Python function that will input the index value and output the group:" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "

df2

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
data1data2
key
A05
B10
C23
A33
B47
C59
\n", + "
\n", + "
\n", + "
\n", + "

df2.groupby(str.lower).mean()

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
data1data2
a1.54.0
b2.53.5
c3.56.0
\n", + "
\n", + "
" + ], + "text/plain": [ + "df2\n", + " data1 data2\n", + "key \n", + "A 0 5\n", + "B 1 0\n", + "C 2 3\n", + "A 3 3\n", + "B 4 7\n", + "C 5 9\n", + "\n", + "df2.groupby(str.lower).mean()\n", + " data1 data2\n", + "a 1.5 4.0\n", + "b 2.5 3.5\n", + "c 3.5 6.0" + ] + }, + "execution_count": 28, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "display('df2', 'df2.groupby(str.lower).mean()')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### A list of valid keys\n", + "\n", + "Further, any of the preceding key choices can be combined to group on a multi-index:" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
data1data2
avowel1.54.0
bconsonant2.53.5
cconsonant3.56.0
\n", + "
" + ], + "text/plain": [ + " data1 data2\n", + "a vowel 1.5 4.0\n", + "b consonant 2.5 3.5\n", + "c consonant 3.5 6.0" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df2.groupby([str.lower, mapping]).mean()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Grouping example\n", + "\n", + "As an example of this, in a couple lines of Python code we can put all these together and count discovered planets by method and by decade:" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
decade1980s1990s2000s2010s
method
Astrometry0.00.00.02.0
Eclipse Timing Variations0.00.05.010.0
Imaging0.00.029.021.0
Microlensing0.00.012.015.0
Orbital Brightness Modulation0.00.00.05.0
Pulsar Timing0.09.01.01.0
Pulsation Timing Variations0.00.01.00.0
Radial Velocity1.052.0475.0424.0
Transit0.00.064.0712.0
Transit Timing Variations0.00.00.09.0
\n", + "
" + ], + "text/plain": [ + "decade 1980s 1990s 2000s 2010s\n", + "method \n", + "Astrometry 0.0 0.0 0.0 2.0\n", + "Eclipse Timing Variations 0.0 0.0 5.0 10.0\n", + "Imaging 0.0 0.0 29.0 21.0\n", + "Microlensing 0.0 0.0 12.0 15.0\n", + "Orbital Brightness Modulation 0.0 0.0 0.0 5.0\n", + "Pulsar Timing 0.0 9.0 1.0 1.0\n", + "Pulsation Timing Variations 0.0 0.0 1.0 0.0\n", + "Radial Velocity 1.0 52.0 475.0 424.0\n", + "Transit 0.0 0.0 64.0 712.0\n", + "Transit Timing Variations 0.0 0.0 0.0 9.0" + ] + }, + "execution_count": 30, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "decade = 10 * (planets['year'] // 10)\n", + "decade = decade.astype(str) + 's'\n", + "decade.name = 'decade'\n", + "planets.groupby(['method', decade])['number'].sum().unstack().fillna(0)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This shows the power of combining many of the operations we've discussed up to this point when looking at realistic datasets.\n", + "We immediately gain a coarse understanding of when and how planets have been discovered over the past several decades!\n", + "\n", + "Here I would suggest digging into these few lines of code, and evaluating the individual steps to make sure you understand exactly what they are doing to the result.\n", + "It's certainly a somewhat complicated example, but understanding these pieces will give you the means to similarly explore your own data." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "< [Combining Datasets: Merge and Join](03.07-Merge-and-Join.ipynb) | [Contents](Index.ipynb) | [Pivot Tables](03.09-Pivot-Tables.ipynb) >" + ] + } + ], + "metadata": { + "anaconda-cloud": {}, + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.4.3" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/pandas/03.09-Pivot-Tables.ipynb b/pandas/03.09-Pivot-Tables.ipynb new file mode 100644 index 0000000..080fd26 --- /dev/null +++ b/pandas/03.09-Pivot-Tables.ipynb @@ -0,0 +1,1376 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "\n", + "*This notebook contains an excerpt from the [Python Data Science Handbook](http://shop.oreilly.com/product/0636920034919.do) by Jake VanderPlas; the content is available [on GitHub](https://github.com/jakevdp/PythonDataScienceHandbook).*\n", + "\n", + "*The text is released under the [CC-BY-NC-ND license](https://creativecommons.org/licenses/by-nc-nd/3.0/us/legalcode), and code is released under the [MIT license](https://opensource.org/licenses/MIT). If you find this content useful, please consider supporting the work by [buying the book](http://shop.oreilly.com/product/0636920034919.do)!*\n", + "\n", + "*No changes were made to the contents of this notebook from the original.*" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "< [Aggregation and Grouping](03.08-Aggregation-and-Grouping.ipynb) | [Contents](Index.ipynb) | [Vectorized String Operations](03.10-Working-With-Strings.ipynb) >" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Pivot Tables" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We have seen how the ``GroupBy`` abstraction lets us explore relationships within a dataset.\n", + "A *pivot table* is a similar operation that is commonly seen in spreadsheets and other programs that operate on tabular data.\n", + "The pivot table takes simple column-wise data as input, and groups the entries into a two-dimensional table that provides a multidimensional summarization of the data.\n", + "The difference between pivot tables and ``GroupBy`` can sometimes cause confusion; it helps me to think of pivot tables as essentially a *multidimensional* version of ``GroupBy`` aggregation.\n", + "That is, you split-apply-combine, but both the split and the combine happen across not a one-dimensional index, but across a two-dimensional grid." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Motivating Pivot Tables\n", + "\n", + "For the examples in this section, we'll use the database of passengers on the *Titanic*, available through the Seaborn library (see [Visualization With Seaborn](04.14-Visualization-With-Seaborn.ipynb)):" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "import seaborn as sns\n", + "titanic = sns.load_dataset('titanic')" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
survivedpclasssexagesibspparchfareembarkedclasswhoadult_maledeckembark_townalivealone
003male22.0107.2500SThirdmanTrueNaNSouthamptonnoFalse
111female38.01071.2833CFirstwomanFalseCCherbourgyesFalse
213female26.0007.9250SThirdwomanFalseNaNSouthamptonyesTrue
311female35.01053.1000SFirstwomanFalseCSouthamptonyesFalse
403male35.0008.0500SThirdmanTrueNaNSouthamptonnoTrue
\n", + "
" + ], + "text/plain": [ + " survived pclass sex age sibsp parch fare embarked class \\\n", + "0 0 3 male 22.0 1 0 7.2500 S Third \n", + "1 1 1 female 38.0 1 0 71.2833 C First \n", + "2 1 3 female 26.0 0 0 7.9250 S Third \n", + "3 1 1 female 35.0 1 0 53.1000 S First \n", + "4 0 3 male 35.0 0 0 8.0500 S Third \n", + "\n", + " who adult_male deck embark_town alive alone \n", + "0 man True NaN Southampton no False \n", + "1 woman False C Cherbourg yes False \n", + "2 woman False NaN Southampton yes True \n", + "3 woman False C Southampton yes False \n", + "4 man True NaN Southampton no True " + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "titanic.head()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This contains a wealth of information on each passenger of that ill-fated voyage, including gender, age, class, fare paid, and much more." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Pivot Tables by Hand\n", + "\n", + "To start learning more about this data, we might begin by grouping according to gender, survival status, or some combination thereof.\n", + "If you have read the previous section, you might be tempted to apply a ``GroupBy`` operation–for example, let's look at survival rate by gender:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
survived
sex
female0.742038
male0.188908
\n", + "
" + ], + "text/plain": [ + " survived\n", + "sex \n", + "female 0.742038\n", + "male 0.188908" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "titanic.groupby('sex')[['survived']].mean()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This immediately gives us some insight: overall, three of every four females on board survived, while only one in five males survived!\n", + "\n", + "This is useful, but we might like to go one step deeper and look at survival by both sex and, say, class.\n", + "Using the vocabulary of ``GroupBy``, we might proceed using something like this:\n", + "we *group by* class and gender, *select* survival, *apply* a mean aggregate, *combine* the resulting groups, and then *unstack* the hierarchical index to reveal the hidden multidimensionality. In code:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
classFirstSecondThird
sex
female0.9680850.9210530.500000
male0.3688520.1574070.135447
\n", + "
" + ], + "text/plain": [ + "class First Second Third\n", + "sex \n", + "female 0.968085 0.921053 0.500000\n", + "male 0.368852 0.157407 0.135447" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "titanic.groupby(['sex', 'class'])['survived'].aggregate('mean').unstack()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This gives us a better idea of how both gender and class affected survival, but the code is starting to look a bit garbled.\n", + "While each step of this pipeline makes sense in light of the tools we've previously discussed, the long string of code is not particularly easy to read or use.\n", + "This two-dimensional ``GroupBy`` is common enough that Pandas includes a convenience routine, ``pivot_table``, which succinctly handles this type of multi-dimensional aggregation." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Pivot Table Syntax\n", + "\n", + "Here is the equivalent to the preceding operation using the ``pivot_table`` method of ``DataFrame``s:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
classFirstSecondThird
sex
female0.9680850.9210530.500000
male0.3688520.1574070.135447
\n", + "
" + ], + "text/plain": [ + "class First Second Third\n", + "sex \n", + "female 0.968085 0.921053 0.500000\n", + "male 0.368852 0.157407 0.135447" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "titanic.pivot_table('survived', index='sex', columns='class')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This is eminently more readable than the ``groupby`` approach, and produces the same result.\n", + "As you might expect of an early 20th-century transatlantic cruise, the survival gradient favors both women and higher classes.\n", + "First-class women survived with near certainty (hi, Rose!), while only one in ten third-class men survived (sorry, Jack!)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Multi-level pivot tables\n", + "\n", + "Just as in the ``GroupBy``, the grouping in pivot tables can be specified with multiple levels, and via a number of options.\n", + "For example, we might be interested in looking at age as a third dimension.\n", + "We'll bin the age using the ``pd.cut`` function:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
classFirstSecondThird
sexage
female(0, 18]0.9090911.0000000.511628
(18, 80]0.9729730.9000000.423729
male(0, 18]0.8000000.6000000.215686
(18, 80]0.3750000.0714290.133663
\n", + "
" + ], + "text/plain": [ + "class First Second Third\n", + "sex age \n", + "female (0, 18] 0.909091 1.000000 0.511628\n", + " (18, 80] 0.972973 0.900000 0.423729\n", + "male (0, 18] 0.800000 0.600000 0.215686\n", + " (18, 80] 0.375000 0.071429 0.133663" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "age = pd.cut(titanic['age'], [0, 18, 80])\n", + "titanic.pivot_table('survived', ['sex', age], 'class')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can apply the same strategy when working with the columns as well; let's add info on the fare paid using ``pd.qcut`` to automatically compute quantiles:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
fare[0, 14.454](14.454, 512.329]
classFirstSecondThirdFirstSecondThird
sexage
female(0, 18]NaN1.0000000.7142860.9090911.0000000.318182
(18, 80]NaN0.8800000.4444440.9729730.9142860.391304
male(0, 18]NaN0.0000000.2608700.8000000.8181820.178571
(18, 80]0.00.0980390.1250000.3913040.0303030.192308
\n", + "
" + ], + "text/plain": [ + "fare [0, 14.454] (14.454, 512.329] \\\n", + "class First Second Third First Second \n", + "sex age \n", + "female (0, 18] NaN 1.000000 0.714286 0.909091 1.000000 \n", + " (18, 80] NaN 0.880000 0.444444 0.972973 0.914286 \n", + "male (0, 18] NaN 0.000000 0.260870 0.800000 0.818182 \n", + " (18, 80] 0.0 0.098039 0.125000 0.391304 0.030303 \n", + "\n", + "fare \n", + "class Third \n", + "sex age \n", + "female (0, 18] 0.318182 \n", + " (18, 80] 0.391304 \n", + "male (0, 18] 0.178571 \n", + " (18, 80] 0.192308 " + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "fare = pd.qcut(titanic['fare'], 2)\n", + "titanic.pivot_table('survived', ['sex', age], [fare, 'class'])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The result is a four-dimensional aggregation with hierarchical indices (see [Hierarchical Indexing](03.05-Hierarchical-Indexing.ipynb)), shown in a grid demonstrating the relationship between the values." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Additional pivot table options\n", + "\n", + "The full call signature of the ``pivot_table`` method of ``DataFrame``s is as follows:\n", + "\n", + "```python\n", + "# call signature as of Pandas 0.18\n", + "DataFrame.pivot_table(data, values=None, index=None, columns=None,\n", + " aggfunc='mean', fill_value=None, margins=False,\n", + " dropna=True, margins_name='All')\n", + "```\n", + "\n", + "We've already seen examples of the first three arguments; here we'll take a quick look at the remaining ones.\n", + "Two of the options, ``fill_value`` and ``dropna``, have to do with missing data and are fairly straightforward; we will not show examples of them here.\n", + "\n", + "The ``aggfunc`` keyword controls what type of aggregation is applied, which is a mean by default.\n", + "As in the GroupBy, the aggregation specification can be a string representing one of several common choices (e.g., ``'sum'``, ``'mean'``, ``'count'``, ``'min'``, ``'max'``, etc.) or a function that implements an aggregation (e.g., ``np.sum()``, ``min()``, ``sum()``, etc.).\n", + "Additionally, it can be specified as a dictionary mapping a column to any of the above desired options:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
faresurvived
classFirstSecondThirdFirstSecondThird
sex
female106.12579821.97012116.11881091.070.072.0
male67.22612719.74178212.66163345.017.047.0
\n", + "
" + ], + "text/plain": [ + " fare survived \n", + "class First Second Third First Second Third\n", + "sex \n", + "female 106.125798 21.970121 16.118810 91.0 70.0 72.0\n", + "male 67.226127 19.741782 12.661633 45.0 17.0 47.0" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "titanic.pivot_table(index='sex', columns='class',\n", + " aggfunc={'survived':sum, 'fare':'mean'})" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Notice also here that we've omitted the ``values`` keyword; when specifying a mapping for ``aggfunc``, this is determined automatically." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "At times it's useful to compute totals along each grouping.\n", + "This can be done via the ``margins`` keyword:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
classFirstSecondThirdAll
sex
female0.9680850.9210530.5000000.742038
male0.3688520.1574070.1354470.188908
All0.6296300.4728260.2423630.383838
\n", + "
" + ], + "text/plain": [ + "class First Second Third All\n", + "sex \n", + "female 0.968085 0.921053 0.500000 0.742038\n", + "male 0.368852 0.157407 0.135447 0.188908\n", + "All 0.629630 0.472826 0.242363 0.383838" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "titanic.pivot_table('survived', index='sex', columns='class', margins=True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here this automatically gives us information about the class-agnostic survival rate by gender, the gender-agnostic survival rate by class, and the overall survival rate of 38%.\n", + "The margin label can be specified with the ``margins_name`` keyword, which defaults to ``\"All\"``." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Example: Birthrate Data\n", + "\n", + "As a more interesting example, let's take a look at the freely available data on births in the United States, provided by the Centers for Disease Control (CDC).\n", + "This data can be found at https://raw.githubusercontent.com/jakevdp/data-CDCbirths/master/births.csv\n", + "(this dataset has been analyzed rather extensively by Andrew Gelman and his group; see, for example, [this blog post](http://andrewgelman.com/2012/06/14/cool-ass-signal-processing-using-gaussian-processes/)):" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# shell command to download the data:\n", + "# !curl -O https://raw.githubusercontent.com/jakevdp/data-CDCbirths/master/births.csv" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "births = pd.read_csv('data/births.csv')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Taking a look at the data, we see that it's relatively simple–it contains the number of births grouped by date and gender:" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
yearmonthdaygenderbirths
0196911F4046
1196911M4440
2196912F4454
3196912M4548
4196913F4548
\n", + "
" + ], + "text/plain": [ + " year month day gender births\n", + "0 1969 1 1 F 4046\n", + "1 1969 1 1 M 4440\n", + "2 1969 1 2 F 4454\n", + "3 1969 1 2 M 4548\n", + "4 1969 1 3 F 4548" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "births.head()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can start to understand this data a bit more by using a pivot table.\n", + "Let's add a decade column, and take a look at male and female births as a function of decade:" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
genderFM
decade
196017536341846572
19701626307517121550
19801831035119243452
19901947945420420553
20001822930919106428
\n", + "
" + ], + "text/plain": [ + "gender F M\n", + "decade \n", + "1960 1753634 1846572\n", + "1970 16263075 17121550\n", + "1980 18310351 19243452\n", + "1990 19479454 20420553\n", + "2000 18229309 19106428" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "births['decade'] = 10 * (births['year'] // 10)\n", + "births.pivot_table('births', index='decade', columns='gender', aggfunc='sum')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We immediately see that male births outnumber female births in every decade.\n", + "To see this trend a bit more clearly, we can use the built-in plotting tools in Pandas to visualize the total number of births by year (see [Introduction to Matplotlib](04.00-Introduction-To-Matplotlib.ipynb) for a discussion of plotting with Matplotlib):" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\nJfd0uLtWowm/plapGR86BgeNPd9e2M4/D7/JncFDubvdsCZ5fiyar0JDEQeyDrP/0iHyKq4A4OXo\nST/fXvTxjcLd3q3JYzIrCpt2neW7n9Jw09oxb2IPAr21ANzVO5D8ogq2J2aw7LOjzJvUA43N709g\nGvWnwtHREQC9Xs+cOXOYO3cu/v7++Pv7X5co6PV6XFz++wzFyckJvV5PaWkpWu3VDjs7O1NSUnLd\nsWvH09PTcXBwwN3d/brj19q41va1NoQQzZe+spRdGXtxtXMhxq9PndpQqVSM7nAXHdzasTZ1M99d\n2E5SzlGmdplAe7fgBo5YNGdV5iqO5p1kX9ZBTuafQkHBVm1LH58o+vn2IsS9vcXqIFSZzHywNZX9\nxy/j4+HEvEndaePmWP15lUrF5OGhXCmp4MjpPD7YepJHRt/2u+Nt9PQ5KyuL2NhYpk6dysiRI294\njlarRa/XV39cWlqKq6srWq2W0tLS6mMuLi7VCcCvz3Vzc8PW1rb6XLiafLi6ulaf7+HhcV3ScCs6\nnRMaTe2fK3l51W+iSHPQGvoIraOfzb2PP6Rsp9JUyZSIsfj73Hi3vdr2cbBXNL07dmNtyhdsOxPH\nkoQVjAgbygPh9+Cgse65TM39+1gblu5jbmk+L+54jdyyq6MHoR7tGNqhP/2DonGydazh6tqrSz/L\nDVW88vEhElNz6BSk428z+uCmvfHf2Wce7sP/rdzH/uPZBPq6MW1El991r0ZNFPLy8pgxYwaLFi2i\nb9++Nz0vIiKCpUuXUllZicFg4Ny5c4SGhhIZGUlcXBzh4eHExcURHR2NVqvFzs6O9PR0AgIC2LNn\nD7GxsdjY2PDqq6/y8MMPk5WVhaIouLu707NnT+Lj4xk3bhzx8fFER0fXGHdBQVmt++jl5WL1xTLq\nqzX0EVpHP5t7H/XGUr49tRNXOxe6u/a4YV/q0sd7gkZxm+ttrDm5ka2ndnAwLYkpne+nk0dIQ4Xe\noJr797E2LN3HiioDryWuILfsCjF+fRgSEIOf1geA0sIqSmmY2OrSz+KySt7YmMz5rBLCO3jy+Lhu\nVJZXklteedNrZo3tysurE9jw4ykcNCqG9PD/TRw306iJwqpVqyguLmbFihUsX74clUrFe++9h53d\n9cVO2rRpw7Rp05gyZQqKojBv3jzs7OyYPHkyCxYsYMqUKdjZ2bFkyRIAnn/+eebPn4/ZbCYmJoaI\n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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "%matplotlib inline\n", + "import matplotlib.pyplot as plt\n", + "sns.set() # use Seaborn styles\n", + "births.pivot_table('births', index='year', columns='gender', aggfunc='sum').plot()\n", + "plt.ylabel('total births per year');" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "With a simple pivot table and ``plot()`` method, we can immediately see the annual trend in births by gender. By eye, it appears that over the past 50 years male births have outnumbered female births by around 5%." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Further data exploration\n", + "\n", + "Though this doesn't necessarily relate to the pivot table, there are a few more interesting features we can pull out of this dataset using the Pandas tools covered up to this point.\n", + "We must start by cleaning the data a bit, removing outliers caused by mistyped dates (e.g., June 31st) or missing values (e.g., June 99th).\n", + "One easy way to remove these all at once is to cut outliers; we'll do this via a robust sigma-clipping operation:" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "quartiles = np.percentile(births['births'], [25, 50, 75])\n", + "mu = quartiles[1]\n", + "sig = 0.74 * (quartiles[2] - quartiles[0])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This final line is a robust estimate of the sample mean, where the 0.74 comes from the interquartile range of a Gaussian distribution (You can learn more about sigma-clipping operations in a book I coauthored with Željko Ivezić, Andrew J. Connolly, and Alexander Gray: [\"Statistics, Data Mining, and Machine Learning in Astronomy\"](http://press.princeton.edu/titles/10159.html) (Princeton University Press, 2014)).\n", + "\n", + "With this we can use the ``query()`` method (discussed further in [High-Performance Pandas: ``eval()`` and ``query()``](03.12-Performance-Eval-and-Query.ipynb)) to filter-out rows with births outside these values:" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "births = births.query('(births > @mu - 5 * @sig) & (births < @mu + 5 * @sig)')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Next we set the ``day`` column to integers; previously it had been a string because some columns in the dataset contained the value ``'null'``:" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# set 'day' column to integer; it originally was a string due to nulls\n", + "births['day'] = births['day'].astype(int)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Finally, we can combine the day, month, and year to create a Date index (see [Working with Time Series](03.11-Working-with-Time-Series.ipynb)).\n", + "This allows us to quickly compute the weekday corresponding to each row:" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# create a datetime index from the year, month, day\n", + "births.index = pd.to_datetime(10000 * births.year +\n", + " 100 * births.month +\n", + " births.day, format='%Y%m%d')\n", + "\n", + "births['dayofweek'] = births.index.dayofweek" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Using this we can plot births by weekday for several decades:" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\nHCMi8XvqGQJnv4Hr7cNRrKzIX/8zx1/+F6femE3hzh2Nui1yez9nZk3uSd+wVpzIKmLWF4ls2pNp\nko2VjFYIrFq1Cnd3d/r27Yter6empoYXX3yR559/Hju7P5ZPFBcX1+lJYG9vT3FxMSUlJbUTFB0c\nHCg2k60ohRDCUrnYOPNA5wno9Do+PbCEkqpSU4fU6DSeXniOuYe2b/4PnymPYx/aibLDaWR98iEZ\nz07nwtfLqDyX1SjnsrNR8+AdnZgysjNqlYovf07j/W/2U9jEk0mNM02Si4WAoihs3bqV1NRU7rzz\nTvz8/HjllVeoqKjg2LFjzJ49m169etX5kC8pKcHJyQmtVktJSUntbX+ngVFDr5dYCsmT4SRXhpE8\nGaY558nTsztZVcP4OuVHlh37huf6TUGlGG9w2ZS58vIZDLcPpuzMGbJ+Xs/5XzeR9/M68n5eh3OX\ncFrddgtuvXqism7Y5kzDPR3pGe7LO8t2s/doNrM+T+TJcd2ICPFupL/k+gzafbChYmJiePXVV2u3\nLs7MzOTpp59m2bJlZGdnM3nyZFauXElFRQVjx45l9erVLFmyhJKSEqZOncqPP/7Irl27mDlzpkHn\na44TcZpac52wZAqSK8NIngzTEvKk0+v4YO+npOYdYVS7YdwSEG2U85hbrnRVVRTvTqJg82+UHU4D\nwMrRCad+/XGOGoDGs2GtmHV6PT8nnGTV5nRqdHoGR/hxT3Q7NNbXX2Zo9MmCjUFRlGte9/Dw8CAm\nJoYJEyag1+uZPn06Go2G8ePHM2PGDCZMmIBGo2HevHlNEaoQQoh6qBQV93cez+yEd/g+fR2BTm0I\ndm1r6rCMTmVtjVOv3jj16k3l2TPkx2+mcNsW8tb+SN7aH7HvHIZzVDTarjfdUF8ClaJwe68AOgW4\n8fGaFDYmnSb1RB4Pj+hEG2/jjYw0yYhAUzOnCtJcmVulbc4kV4aRPBmmJeXpaH4G7+75CEdrB17o\n+RSOmsZtPNcccqWrqqR41y4K4jdRduQwAFbOLjhfGiWwdve4oeNWVNXw9W9H+XV3JmorhdFR7bi1\npz+qqyzbNHpnweaouXTtMqXm1N3M1CRXhpE8GaYl5cnN1hVrlZp92SmcKsqkR6tujdpfoDnkSrGy\nwsbfH+d+/dFG9EBRqag4kUHpwRTyN66nPCMdla0t1p5eKCrD51KorVR0aedBkI8jB9Jz2X0kmyOn\n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\nz7DXppEAAAAASUVORK5CYII=\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import matplotlib.pyplot as plt\n", + "import matplotlib as mpl\n", + "\n", + "births.pivot_table('births', index='dayofweek',\n", + " columns='decade', aggfunc='mean').plot()\n", + "plt.gca().set_xticklabels(['Mon', 'Tues', 'Wed', 'Thurs', 'Fri', 'Sat', 'Sun'])\n", + "plt.ylabel('mean births by day');" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Apparently births are slightly less common on weekends than on weekdays! Note that the 1990s and 2000s are missing because the CDC data contains only the month of birth starting in 1989.\n", + "\n", + "Another intersting view is to plot the mean number of births by the day of the *year*.\n", + "Let's first group the data by month and day separately:" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "1 1 4009.225\n", + " 2 4247.400\n", + " 3 4500.900\n", + " 4 4571.350\n", + " 5 4603.625\n", + "Name: births, dtype: float64" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "births_by_date = births.pivot_table('births', \n", + " [births.index.month, births.index.day])\n", + "births_by_date.head()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The result is a multi-index over months and days.\n", + "To make this easily plottable, let's turn these months and days into a date by associating them with a dummy year variable (making sure to choose a leap year so February 29th is correctly handled!)" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "2012-01-01 4009.225\n", + "2012-01-02 4247.400\n", + "2012-01-03 4500.900\n", + "2012-01-04 4571.350\n", + "2012-01-05 4603.625\n", + "Name: births, dtype: float64" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "births_by_date.index = [pd.datetime(2012, month, day)\n", + " for (month, day) in births_by_date.index]\n", + "births_by_date.head()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Focusing on the month and day only, we now have a time series reflecting the average number of births by date of the year.\n", + "From this, we can use the ``plot`` method to plot the data. It reveals some interesting trends:" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAskAAAEMCAYAAAA2+Ct3AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzsvXl8XOV59n+d2XfNjGa077LkVd4BOwbHIZCQkDYp4CZ2\nYkrrX9/ShOZ9S0ISSt9A2iahbQjk80l4myakrQ117IQlYQkBUjAGGxuvsqzV2tfRaPZ9Pb8/zpyj\nmdFskiXLku/vP5jRmZnnmZlzzvXcz3XfN8OyLAuCIAiCIAiCIAREiz0AgiAIgiAIgrjWIJFMEARB\nEARBEGmQSCYIgiAIgiCINEgkEwRBEARBEEQaJJIJgiAIgiAIIg0SyQRBEARBEASRhqSQg+666y5o\nNBoAQFVVFb73ve8BAF5++WU899xz+OUvfwkAOHLkCA4fPgypVIr7778fu3btQigUwkMPPQSbzQaN\nRoPHH38cBoNhgaZDEARBEARBEFdOXpEcDocBAAcOHEh5vL29Hc8//7zw/1NTUzh48CBefPFFBINB\n7NmzBzt27MChQ4fQ3NyMBx54AK+99hqefvppPPLII/M8DYIgCIIgCIKYP/LaLTo7O+H3+7F//37c\nd999uHDhApxOJ5566qkUsdva2ootW7ZAIpFAo9Ggrq4OnZ2dOHPmDHbu3AkA2LlzJ06cOLFwsyEI\ngiAIgiCIeSBvJFmhUGD//v3YvXs3BgYGsH//fjQ1NeFb3/oWZDKZcJzX64VWqxX+X6VSwev1wufz\nCVYNtVoNr9e7ANMgCIIgCIIgiPkjr0iuq6tDbW2t8O+xsTGIxWI89thjCIVC6O3txfe//33cdNNN\nKQLY5/NBp9NBo9HA5/MJjyUL6WywLAuGYeY6J4IgCIIgCIK4IvKK5Oeffx7d3d149NFHYbFYUF9f\nj1dffRUMw2B0dBRf+9rX8PDDD2NqagpPPfUUwuEwQqEQ+vr60NTUhE2bNuHo0aNoaWnB0aNHsXXr\n1ryDYhgGVqtnXiZ4rWI2a5fdHJfjnNJZznNcznPjWc5zXM5zA5b//IDlPcflPDee5TzH5T63bOQV\nyffccw8efvhh7N27FyKRCN/73vcyRnlNJhP27duHvXv3gmVZPPjgg5DJZNizZw+++c1vYu/evZDJ\nZHjiiSeubDYEQRAEQRAEscAwLMuyiz2ITCzXFQvPclyVLcc5pbOc57ic58aznOe4nOcGLP/5Act7\njst5bjzLeY7LfW7ZoGYiBEEQBEEQBJEGiWSCIAiCIAiCSINEMkEQBEEQBEGkQSKZIAiCIAiCINIg\nkUwQBEEQBEEQaZBIJgiCIAiCIIg0SCQTBEEQxHVEPM7iR7+6gNdPDhV0fCgSQ2uvDS8d64PF4V/g\n0RHEtUPeZiIEQRAEQSwfJux+XOi1oXfMjdtvqIJYlD1eFonG8Xf//gEcnhAAYHjSi7+5e/3VGipB\nLCoUSSYIgiCI64hBC9cUwhuIoGfYlfPY7mEnHJ4Q1tYbUWZUobXXBm8gcjWGSRCLDolkgiAIgriO\nGLJMd047223NeeyF3ikAwKduqsEtG8oRi7P4sHNyQcdHENcKJJIJgiAI4jpicIITyUq5GGe6rWBZ\nNuuxrb02KGRiNFfrsW1NGRgAJ9omrtJICWJxIZFMEARBENcJLMti0OJFqVGFjSvMcHhCGJjwZDx2\nwu7HpCOAtXVGSMQiGLRyrK4z4PKoC5POwFUeOUFcfUgkEwRBEMR1gtUVRCAURW2pBpubzQCA01ns\nE62XOavF+sZi4bFta8oAAB92WBZ4pASx+JBIJgiCIIjrhKFE1Li2TIuWBiOUcglOXJpAPD7TcnE+\ng0je2GQCwwAXem1XZ8AEsYiQSCYIgiCIJczZbivOdOVOwOPhK1vUlmohk4px0+oSOL1hXBqwIxSO\noWvIAZZl0T3sROeQE83VehRp5MLzNUopVlQWoXfUBY8/vCDzIYhrBaqTTBAEQRBLmP96vRPhSBwb\nVtwCiTh37IsXyTWlWgDAjvXleOf8GN4+O4rfvt+P3lE3bt9ajcujXGm4e3Y1zniNDStM6Blx4WKf\nDR9ZVz7PsyGIaweKJBMEQRDEEiUQisLjjyAUiaFvzJ3z2DjLon/MDVORAhqlFADQUK5DebEK5y9P\noXfUDalEhDdPD6N/3I2tq0qworJoxutsSNgvzvVM4cV3+/CTFy5mtGsQxFKHRDJBEARBLFGsSVUm\nLvXbcx47MumFLxjFqhqD8BjDMLi5hYsGr6414Pv/axvKi1WQSUUZo8gAUGFSw1SkwJkuK14+PoAz\n3VaMWL3zMBuCuLYguwVBEARBLFGSRXL7gB1/srMh67Edgw4AnBhO5ratVdCopNi6sgRKuQSP/fmN\n8AcjKV7kZBiGweZmM974cBgGrRwOTwh9Y27BwkEQywWKJBMEQRDEEoWvVyxiGPSNu+EPZm8ZzYvk\nVWkiWSoR45b1FVDKJYn/F2UVyDx37WzA1z6/Ef/7nvUAkNHqEWdZTDr8OZuVEMS1TEGR5Lvuugsa\njQYAUFVVhXvvvRf/+I//CLFYDJlMhn/5l3+B0WjEkSNHcPjwYUilUtx///3YtWsXQqEQHnroIdhs\nNmg0Gjz++OMwGAx53pEgCIIgiHxYnUEAwKYmE850W9E55BTqHycTjcXRNexEqVEFgza3AC4EmVSM\ntfVGxOMs5DIxesdcKX9//+I4XjkxCIvdj/s/uxZ3luiu+D0J4mqTVySHw1yJlwMHDgiP7du3D9/+\n9rexcuVKHD58GD/72c+wf/9+HDx4EC+++CKCwSD27NmDHTt24NChQ2hubsYDDzyA1157DU8//TQe\neeSRhZsRQRAEQVwnWB1+AMBHN1bgTLcVlwbsGUXy4IQHoXBshtXiShGJGNSXadE55IQ/GIFKIUX/\nuBvPvNoBEcMAANr67Lhz57y+LUFcFfLaLTo7O+H3+7F//37cd999uHDhAp588kmsXLkSABCNRiGT\nydDa2ootW7ZAIpFAo9Ggrq4OnZ2dOHPmDHbu5M6OnTt34sSJEws7I4IgCIK4TrA6g9CpZVhVa4BM\nIsLlEVfG47L5keeDxkQFjP5xrrxcWx/XaOQv/2gNlHIxekYzj4kgrnXyimSFQoH9+/fjmWeewWOP\nPYavf/3rMBqNAICzZ8/iv//7v3HffffB6/VCq5027atUKni9Xvh8PsGqoVar4fVSBixBEARBXCmx\neBw2dxBmvQISsQg1ZVqMWn0IhWMzjuXrHq+s1s/7OBrKOStFX8Jy0THoAANgbb0RDRVFsNj9cHlD\n8/6+BLHQ5LVb1NXVoba2Vvi3Xq+H1WrFmTNn8NOf/hT//u//DoPBAI1GkyKAfT4fdDodNBoNfD6f\n8FiykM6F2bz8s2SX4xyX45zSWc5zXM5z41nOc1zOcwOW//yA2c1xwuZDLM6iulQHs1mLtQ0mXB5x\nwRWKYW1lqhj2BCJQysVorCvO8mpz5wa5FHjhIoan/NAWKXF51I36yiLU1xixobkEl/rt6Byw46br\noPHIcv6NLue5ZSOvSH7++efR3d2NRx99FBaLBT6fDydPnsThw4dx8OBB6HTcCnL9+vV46qmnEA6H\nEQqF0NfXh6amJmzatAlHjx5FS0sLjh49iq1btxY0MKvVc2Uzu8Yxm7XLbo7LcU7pLOc5Lue58Szn\nOS7nuQHLf37A7OfYNcDVRdYpJbBaPSjTKwAA5zomUKKVpRxrcwagU8sX7DM06xVovWzF7471IRqL\no7myCFarB+UGbkwdA3Y0lGoW5L2vFZbzb3S5zy0bee0W99xzDzweD/bu3Yuvfe1r+O53v4vvfve7\n8Pv9+MpXvoJ7770XP/7xj2EymbBv3z7s3bsX9913Hx588EHIZDLs2bMHPT092Lt3L371q1/hgQce\nmNfJEQRBEMRsiMbieP5or1A+banCj9+sVwIA6iu4oFX/eGo5tmgsDrc/AoMmVTjPJ5/ZXodwJI4D\nv+8CAKyu47zPDeU6MAwnkgliqZE3kiyVSvGDH/wg5bGTJ09mPHb37t3YvXt3ymMKhQI/+tGPrmCI\nBEEQBDF/XOy14dUTg4jG4vj8rU0L9j7RWBxObwimIuWCvL41TSSbE+2m02sWu31clSp9ntrHV8KO\n9eV4t3UMvaNuiEUMmqs4u4dSLkG1WYOeYSci0TikEmrPQCw+gxMe/MdrHfjyXS1XFkkmCIIglhcs\ny+ZsOrHcGU60UOZrDC8UrxwfwMM//QCjC9SymR8/L5IZhkF9uQ5TriCc3hAGJzxgWRaORNJc0QJG\nkkUMg32fWAkRw6CpqghymVj424qqIkSicQxZlud2PbH0ONY6hqFJLy6POHMeRyKZIAjiOoFlWZzu\nnMSjv/gQf/PUMQxOXHuiJc6y89KhLRyJYWzKl/FvI5OcaJ2ahd0iEo2hf9yN+CzGdmnAjlicxeku\na8HPmQ0ubwgMAxSpp8VvfTkXFfvOf36I7/znhzjbbYXTs/CRZACoKdXikXu34P/7zJqUxxuy2EAI\nYrHoGuLEcSgSz3kciWSCIIjrhJ4RF55+qQ0jVi9YAN15oihXm0Aoisd+cQo/ebHtil/rN+/149vP\nnMKUa6YQHrZy4tnqCuQV5CzL4qVjffjaT47jH//rNJ55pQOxeO4bKwBEonEMTnBi/FzPwohkbyAC\ntUIKkYgRHqtPlGNzeTlh3D/ugcvHRZIXWiTz72/UKWY8xo+FIBYbty+M0cQCOlO5xGRIJBMEQVwn\n2Fzc9vzODVwprgmbv+Dnun1hoUnEQvHfb3ZjxOrD+Z4pBELRK3qtnhEX4iwLiz1VJIciMUzauXkH\nQjH4grnfp33Qgd++PwAAKC9W4cSlCTz9YlveiPLwpBfRGCemhyxe2N3zb+3w+CPQqqQpj62tN+LO\n7bX480+vAgBM2P1wenmRvHB2i1yUGlVQyiUYmKBIMrH4dA1PBwfCURLJBEEQBLhauQCwssYABsC4\nLbMdIRP/9XonfnjkAoYnC/fXvnNuFIfe6ino2FMdFrzfNgGG4SwX3cNzj3LHWVYYp8OT2sRibMqH\nZHmbKdKcDO+j/bM7VuL//tlWNFfrca5nCj15xtebaKzRWMlFUc/1TM1mCnmJsyx8wQg0ylSRLBGL\ncPdHG3FzSzmUcjEnknm7hXbhI8mZEDEMVlTpMWHzX/HihyCulM5E90mAWzTngkQyQRDEdYI3wIml\nYp0CxUUKjNsLiyQ7vSFcuMxFkVt7CxN7cZbFi8f68Obp4YLE+GsfDEIiZvClT6wEMN1GeS5YnQHh\n5udI6/TG+5ErTGoAwFSe5D3++KoSDRQyCW7bUgVguoNdNnoTf79rZyMA4Pzl+RXJ/mAULIsZIpmH\nYRiUGlSYdPhh93Bz1KsXRyQDQFO1HiyAgWvQB09cX3QOTV9bwmHyJBMEQRAAvH4ukqxRSlFWrILL\nG4Y/j90AAI63TQj2got9hdW7HbZ44Um8Hy+wsxGOxDAy6UNtmRY71pVBIhalRHtmy7BlOtrtTIsk\n85UtNjWZAEyXUcv6WpM+yKQioYJEY2URAKB3NLd1oG/MDY1SilU1etSWatE56JhXy4U3MP1dZqOs\nWIVojEX/uBtKuTil4sTVpqmGKwk3QMl7xCLi8oYwbvOjJHE+UySZIAiCADBtt9CopCgzqgBwntVc\nsCyLY63jkEpEqDCp0TvqKkhYX0pqHnE+T+La0KQXcZZFfZkOMqkYKyp1GJr0wuMP530ffoxTzgBa\ne6cQisQwlGQJcWaJJG9oTIhkV3bhGo3FMW7zocqsgYjhkuMMWjmKdXJcHnVlTfpzeUOYcgXRUKED\nwzC4bWsVYnEWv3mvv6D5FIKw4FHlEMmJ7zgQil2VpL1cNFVzzUWowgWxmPQlfn/rGowAyJNMEARB\nJPD6I2AAqBUSlBdzdoN8VoieERcsdj+2rDRj60ozYnG2ICvEpX5OJJcXq9Az6hIin5noTzS/4Ksg\nrK7jbmB8maaccwpE8OgvPsQ3/u0EnvpVK379di+GEz5ihkn1JLMsixGrDyV6JSrNvN2CiyTHWRZv\nfjiMl9+fFrLjNj9icRZV5tR2yo2VRfAGIlk79vHNPPio8/a1ZagwqfHexfFZ+cBz4UlYZ7TK7Ml4\nvEgGrk5li1yUGJTQKKVktyAWlZFEZRv+3KTqFgRBEAQAwBuMQKWQQCwSobzASHJPokzc1pUlWNdQ\nDABo689tnwhFYugZcaKmRIOPrCsDy+b2Mvcnqh7UJWr8rq7loo7tBYjxX/6hByNWL9bUGaDXyLiu\nb2NuFGlkKNYpUjzJ7QMOeAMR1JRpoZRLoFFKYXUF4faH8eTh8zj0hx68eKxfsEXwUefqkjSRXMFb\nLjL7kgcTIr2+jJuPSMTgT25pAMsCLx6bn2gyv+hQK7M3zk0VyYtT2YInudFJvmRJglgo+MY+fO1u\nslsQBEEQALhIskbFiaXyYk5AjecpA8eLMb1GjoZyHdQKCS722XLWF+4ZdiIaY7G23oiNTWYAwPkc\n1R36xz1QyiUoTYi6ujItZFJR3goSrb1TON42gdoyLf72Tzfgzu11iETj8AYiqC7RwKCVw+0LIxaP\nIxSJ4cDvOyFiGNy5rRYAYNYrYHMF8NPfXMKlAYfQlINPyuP9y1WJqDNPPl/ycAZxvbnZhOoSDc51\nWwu2keSC/15yRZJLDddOJBngPgMAONluWeSRENcro1M+yGVimPVKSMQMNRMhCIIgOKuBNxCBJhF5\n1KllUMolebf/vUk+ZpGIwdp6I+zuEMZyiOsLvVykeW29ERXFKhTrFOgccmasLewPRmCx+1FXphV8\nvxKxCI0VRRid8mW1aYTCMRz4fRfEIgZ/8enVEItEuHl9uZDIVlOihUErB8tyjTVefn8AVmcQn7ih\nGrWJCK+pSIlojLOPbGgsxl9/bh2AafGbXNkimZpSDaQSUdZI8vCkF1qVFLqkTngMw2D72rJ568BX\niCdZLhPDqOPE8bUgkm9YVQKJWITjbRPz0lWRIGZDNBbHhM2PSpMaIoaBXComTzJBEATBJW/F4qwQ\neWQYBuXFKkw6Ajk7yAliTMGJsXX1CctFlsYigVAUx9vGUaSWoblaD4Zh0FzNeXgzNS/hPaq8H5mn\nqYqL1mYrtfa7k4Owu0P45I01QsRWLhXj9huqAQCNFTpBGNrdIfzh7AgMWjk+e3O98BomPdcZTiET\nY98nV6KuTAuxiEmJJBt1cqgVM2sR15dpMWz1zlhkBEJRTLmCqC7RgGGYlL/duLoEwPxEUj1CJDm7\nSAamLRdFi2y3AACVQoqNK4oxbvNjyFJ4vW2CmA8m7FyOQWWi/KNMKiZPMkEQBDFdIzm5ZFhFsRqx\nOCu0T874vGAEYhEDpZwrH8ZnhWcTye9dHEcgFMOtmyshEXO3mKYqrvxXT4Y22Hy1g/qEH5mnqXr6\nOdFYHOe7J4VI9JQrgN+dHEKRRobPfKQ25Xl3bqvFN/duwsYmkyCSL/ROIRSOYUNjcUoZtNpS7j3/\n9GMrYNQpIJOKUVOqxZDFg8EJD1zeMKrTkvZ4br+hBiwL/Ort3pTHRwSLxsznGXUKNFcVoWfYecXl\n4AqJJAMQEjTTW0UvFtvXlgHgygoSxNVkNJG0x5+bcqkYYfIkEwRBEMnl33i2ruL8wu9dHM/6PK8/\nArVSKkRF9Ro5qks06Bp2zojCxONchQipRIRdmyqFx/mocM/IzKjwYCKSXFeWGkluKNdBxDDoGXHh\n1+/04v/+9ATOJmwKLx3rRyQax+5djVDIUhPXRCKG6yjIMDAkOsx92DHJjSMhvKfnX4J/uX97ylgb\nK3WIxVn87JV2AMDN6ysyfi6bm01ortbj/OUpdCSVu8vkR07mpjWlYAGcSoxprniDETAMoJRnT9wD\ngE/dVIO9tzWhsUKX87irRUtjMdQKCU53TZLlgriq8AtYvrKNTCoiTzJBEAQxHXlM3p5fW2+EXiPD\nyfaJrFnenI85NVq5rsGIaIxN6VwFAK29Nky5gti+tgxa1fT2frlJDbVCkjGSPDzphUouEbyzPEq5\nBNWlGvSPufGHMyMAgO5hJ1iWRWuvDQatHNsSUcls8CKZL9XGi3UeEcPAlGgqwLMikZQ3NuVDpUmN\nTYlks3QYhsEXPr4CDIAXjvUJj2eriMGzdVUJxCLmin25Xj/3vYjSLB3pGHUK3La1eob1Y7GQiEVY\nWWOAwxOa0TKcIBYSPpJcSZFkgiAIIplMHdrEIhF2tJQjEIoJUdpk4nEW/mB0hkhez5eCS+u+x3t5\nt60pTXlcxDBorCyC1RlMae4RCscw6QigpnSmfxfgRG0sziIW58Rk75gLE3Y/vIEImqv1eQWiXjst\nvI06OUxFyhxHc/AiGQDu/EhtzveoK9NhZY0efaNu4fMdnvRCLGIEm0M6WpUMG1aYMGL1YtDigd0d\nxKG3enLWkc5EpsXLUoG31iQ3FvEHI3jpWB/c81D5gyAyMTrFJdTyVWzkUjHyLVNJJBMEQVwHeLJ4\nWG9ZXw4AONY6NuM5vmAELGa2Pm6sLIJCJsbFtHrJlkTNZb68XDJCIl6S5WLE6gWLmdUjeJoTXuY1\ndQY0VesxZPEKjUySxWw29EnVJXhfdD6MOgUqTGpUmtW4cVVp3uNX1RjAgotyxxPNSsqKVZBKst9e\nb+Y/8wvj+MVrHXjz9DDOdhde8SIeZ+ELRPIm7V2rNCSSNPuSRPKRt3vx2/cH8Ms/9CzWsIhlTCgS\ng9UZFJL2AE4k54NEMkEQxHVAtrq6JQYVVlQVoWvIOaPd9HT0OdX3KhGLsLrWgElHABbHdMWKCbsf\nSrk4pfQZDy9S3zozIjQwyeff3dhkwu6PNWL/nWuwqs6IWJwVrBfp1olMyKRiqBXc2JsLOJ7n7760\nBX/3pS0QifJbFFYlGp90DDpgdQQQisSyzoenpcGIIo0MR8+PoX2AE/0ub+HWA2Hxolr8ihVzoa5c\nBwbTnRaHLB4cu8At0j64ZBF86gQxX7h93A5FcgKrTJpfApNIJgiCuA4QqltkqIbQXKUHC6Bv3JX2\nHF4kzxRjLWmWi3ichcURQKlBldE60VChQ3O1Ht3DTjzysw9wpssqiOSaEu2M4wFOjH/qploYtHJB\njI7bOCGeqXpEJnhfcqGRZABQKSR5E+J46st1kElE6Bxy4P02LgGyOc97iUUi3NxSjjjLgv+kXL7C\nbQbZFi9LBaVcgnKTGv0THsTjLH75hx6wAD61rQYAcOTty5TUR8wrviB3zqgU0+dMIZHkgs6wu+66\nCxoNd0GqqqrC/fffj29961sQiURoamrCo48+CgA4cuQIDh8+DKlUivvvvx+7du1CKBTCQw89BJvN\nBo1Gg8cffxwGg2HWEyQIgiBmMmH34we/PId4HNCppPjqPeszlvsS7BYZtugbK7nt795Rt1AHGcjs\nY+bhS8Fd7LPh41uqYHMHEY3FUZbBagFwgvcbezfhbJcVP/3tJfzmvX4oZGKIGAYVpszPSWZlrVH4\nd0NFUUFRXgDYsMIElVyCCnNmj/CVIpWIsKKqCO0DDtjdQWiUUmxflzuhEAA+urECH1yawM6NlXjx\n3b45iuSlGUkGOF/y2JQPLx7rQ+eQE+sbi7F71wqMTPpwsc+G7mEnVtaQViDmB19il0yTVPNcNh92\ni3CYO3EPHDiAAwcO4Hvf+x6+//3v48EHH8Szzz6LeDyOt956C1NTUzh48CAOHz6Mn//853jiiScQ\niURw6NAhNDc347nnnsNnP/tZPP3003OdI0EQBJHG+xfHYXeHEInFMTTpzdp8wxvgSoYlR1J4Giv4\nNsvZIskzRbKpSInyYhU6hxyIRGOCH7nMkF3wihgGW1eVYHOzGSNWL3pHXSgvVkEqyX+zKjEohYSb\nQqwWPHd/tBHf+tKWvEl+V8KqhJgLhGK4bWtVQREqU5ES//rlHbhzG5ccmEkku31hPPtGF85fTm3p\n7c2x4Fkq8L7kV08MQiYVYe/tzQCATyeiye9eyF6WkCBmC28lm20kOa9I7uzshN/vx/79+3Hffffh\nwoULaG9vx9atWwEAO3fuxPHjx9Ha2ootW7ZAIpFAo9Ggrq4OnZ2dOHPmDHbu3Ckce+LEiTlNkCAI\ngkiFZVmc7pyETCrCX36Wa6nMR4zT8QYiUCsylwzTqWUo0SvRO+ZOaR2dSyQDnOUiHImje9iF8YRI\nLjXmjwrftrWKGz+y+5HTYRIVMgCgqYCkvasJbwWRS8W4dXPVrJ4rEjHQqqVwe1NF8qUBO779i1P4\nn7OjeCmpxByQ1G0vTyORa5n6pLrN93y0ESWJUnzN1XqUGJQ40zU5wyNPEHPFlzhn1CmR5HnwJCsU\nCuzfvx/PPPMMHnvsMXz9619P8Qqp1Wp4vV74fD5otdO+MpVKJTzOWzX4YwmCIIgrZ9Tqg8URwPqG\nYpQkxKk7y7a9xx/JKaoaK3UIhKIYT2odnU8k85aLC71T05HkAkTyisoiodtdoSIZAD7zkVp8alsN\nmmsK9xdfDerLtdjQWIy7Ptowp+hukVqWEkm2u4P48fMX4QtEoFNJMTLpS2ncku97WQpUmTUo0siw\nutaAW7dMLywYhsHNLeUIR+M41XHl7bsJApj2JKuV8+xJrqurQ21trfBvvV6P9vb26Tf2+aDT6aDR\naFIEcPLjPp9PeCxZSOfCbC7suKXMcpzjcpxTOst5jst5bjzLaY5vnh0FANx6Q63QgjkcZ2fMkat3\nHEFNmTbr/DesLMWJSxZMukPYuJrz1MZYLupcU6WHOUOi3A69Cj97uQMn2ydRXcr9fW1zSUFJb1/6\n9Go88dwZ3LKluuDv5IaWStzQUpn/wEXgn75885yfazaoMGTxIhCKwmzW4he/60QoEsPf/OlGjEx6\n8eI7l+EIRNFSyS0OgokuYdUVRUvq95w+1p/93e2QSkRC+3KeP961Ai8d68MHHRbs/sSqqznEK2Yp\nfR+zZSnPjWW431hl2fQ5YzLmz1PIeyV7/vnn0d3djUcffRQWiwVerxc7duzAqVOncOONN+Ldd9/F\ntm3b0NLSgieffBLhcBihUAh9fX1oamrCpk2bcPToUbS0tODo0aOCTSMfVuvyLgFjNmuX3RyX45zS\nWc5zXM5Zl6RMAAAgAElEQVRz41luc3z37AgkYhFqzSoUJUTypM03Y47eQARxFpBLRFnnX5roeHe+\n04JNiQix1c4FOMKBcNbn7dxQjldPDKK93w69RgavO4BC9gsbSzX4yd/uBMMwBX0ny+27S0aZiGg5\nPEGcarXhvQtjaKjQYUO9AfEIZzk4fWkcZUVysCyLExfHoZCJoZWJl8xnMtvvb219MS722dDWbUFp\nDp/7tcRy/o0u9blNORLXsuD0tSwcyt/AJ69Ivueee/Dwww9j7969EIlEePzxx6HX6/H3f//3iEQi\naGxsxB133AGGYbBv3z7s3bsXLMviwQcfhEwmw549e/DNb34Te/fuhUwmwxNPPHGFUyUIgiDs7iBG\np3zYuMIEpVwitCjO5En2B2f68dKpKlFDLhWjO6nZh49P9ssRGf7Ypkr87oMhxFm2IKtFMtdKq+TF\npkjDJSQ63CG8fnIIAPClTzQLnQqB6aTKQYsHNncQ29aU5mxYstTZ3GzCxT4bWi/bcPsNKpzttsJU\npEBN6dKNZhKLB1/dIsWTXEDCcF6RLJVK8YMf/GDG4wcPHpzx2O7du7F79+6UxxQKBX70ox/lHQhB\nEARROHxDDt7TKxIx0KqkGdv6BhN+VoUs+01BLOIahJy/PIVJhx8lBhU8fLJfjnJrRp0CW1eZcapj\nctYimeDgm684PSEMWTwwFSlQV8Yltuk1cpiKFOgdc4NlWZxJtA/fstK8aOO9GqxvNAHowoXeKaxr\nMOLHL1zEymo9vvnFzYs9NGKBaeuzobxYjeKimaUs5wqfuJda3YKaiRAEQSxLrM4AAMCcqAoAcGLL\nk0EkhyKcSJbnEMkAsL6Rq5F8MdEgxBeIQF1ActgdN9VALhVjdZ0x77HETPjSdv1jLrj9kRmNUhor\ni+ANRDDpCOB0lxUyqQjrGoozvdSywaCVo7ZUi64hJ149MQgAsLmDizwqYqGxOPz44ZELePy5MylJ\nyJdHXPjvt7oRi8fn9Lr+YBRymTjF/y7Lcz0ESCQTBEEsSaZcnGAw66ejLTqVFIFQDJFoLOVYvjJC\nvmxuvotea68NLMvCG4hCW4BIrivT4Sd/uxM3rCqZ1RwIDl4kn+/mosRVaRU/GhPl0g78vgsWux/r\nG4oLysxf6qxvLEYszuJ42wQAwOEJpZQoJJYffAdPmzuEH794EZFoHPE4i2de68Bbp0fQPz43X7Qv\nGBVa1PPMS51kgiAI4tojUyRZmxBb6b7kQiPJxUUKVJrV6BxywOULI86yBZcZK7QDHjETPumyZ9gB\nYGZZvNV1RjAAOga5vxfS0W85sGGFSfi3iGEQi7NCIxViedLWZwMArKkz4PKICwd/34VTHRahxORE\nUonK2eALRqCSp17LCum4tzQbvxMEQVznWJ1BSMSMUPoNAHQqTiS7/eGU1tSCJ7mAm8L6hmL87uSQ\n4H1NritKLAx8JDmeCJJWpbXQrjSp8fj92xEMx6CSS+bVq3ktU1euRZFaBn8oii0rzfjgkgUOT0jw\ncBPLi0g0js4hJ8qMKnz17vV4/LmzeO/iOD7smhSO4XMxZkMsHkcwHINGSZFkgiCI6wKrM4DiImVK\nBJdvFpLeUKTQSDIw7Uvmu7xplSRIFhqFTAxZolKFVCJCiUE54xizXonqEs11I5ABLnr8N3evx4N/\nukGIrts9M33JHYMO/Oqdy4jG5uZXJa4NLo84EYrEsK7eCJlUjL+5ez2KNDKEwjHhujQXkTzdkjo1\nkkyJewRBEMuQQCgKbyACc5pgEiLJvjS7RYGeZABoqtLjY5srEUkIDnMGwUbMLwzDCNHRCpMaYhHd\nmnkaKnRYWWOAIbFj4vSEZhzz8vv9+N0HQ3jm1Q7yLC9h2vo5PzLfydOgleNvd2/AzS3l+LM7VkEp\nF2Pc5pv16/oEkZwaSSa7BUEQxDJkOmkvVcBOe5JTI8mFlIDjEYkY7PvESvzpx1ZgxOoV2kcTC4te\nI8eUK4jqDJ0NCU4wAYA9TSSzLItBC9e+5mS7BcU6Be7Z1XjVx0dcOZf67ZCIRVhZbRAeqynV4i/u\nXA2Aa3k/ZPEiFo/PaiHJt6TWpEWSRQyTt9Y4LVcJgiCWGJmS9oBpb2t6reTZ2C145FIxGiuKZrQM\nJhYG/rtL9yMTHIaEx96RJpKtriACoSjW1Rth0Mrx1plhsBRNXnLEWRajUz5Ul6izXqfKjCrE4qwQ\nJCgUf5ZIMpB/d42ufgRBEEsMXiSb0uwW057kLNUtroOyYUsVvuteevk3gsPAdyVME8lDE1xJsNW1\nBjRWFiEcicPpnVkrnLi28QYiiMVZGLTZPfdlxdwCcrYVLvhGIplqvufzJZPdgiAI4hqBZVn8z9lR\nFOsU2LCiOGvb5ilnFruFKrPdYjaeZGJxuHVzFcxGNVbW6Bd7KNckUokYGqV0pkie5ERyTakW/hAX\nMbTY/YI9g1ga8F5zvSZ7onB5oqPnhN2PDbN47emW1DMlbz5fMolkgiCIa4TeUTeee7MbAFBbqsVX\n/mQdTPqZiXNWV2a7hVwqhlwmnmG3mI0nmVgcKkxqbFhdBqt1bs0SrgeMWjksjgAGJtx48sgF/OVn\n1mBwgvMj15RqBAE94fBjVa0h10sR1xh89D+5pGU6ZUkieTb4gzNbUvPkE8lktyAIgrhGuJgopF9b\npsWgxYNXTgxkPM7qDECtkGS86OtU0qwl4ArJ5iaIaxW9Vo5QJIbffTAEjz+CX7/TiyGLB0adHFqV\nDKVGbtE4aQ8s8kiJ2eL0cgucXDsAJQYlGMzBbiFEkjPZLUgkEwRBLAna+m0Qixg89IWN0GtkON1p\nRSSaWvt1yOLBpCOA0kRUJR2dSgaPP5KSvBSKxCARiygJj1jSGBMC6nSiucTQpBcuX1iowFJq4M4J\ni2NuXdmIxWPabpFdJMukYhQXKTA+y0gyX90ik92CRDJx1ekeduKhp49jbGr29QwJ4nrF4w9jYNyD\nFZVFUCmk2LamDP5QFK29NuGYSDSGn73cjlicxR/vqMv4OlqVDLE4K/gzAc6TXEjhfIK4luGjjCwL\nrErybtckRLJWJYVSLobFcf1Fkpd6IxU+kpzLkwxwtiS3LwyXr/DkzGzNRID8iXt01VxmWJ0B/Ofv\nOhEMR/MfvEBc6rfD5g7iVIdl0cZAEItJJBrDibYJ/PDwefz+1FBBz7k0YAeL6UL629aWAgA+aJ8A\nwLVWPfhGN0anfLh1cyXWN5oyvg7fRprfYgQ4TzL5kYmljj5pK/5ztzRgQ6ILGx9JZhgGJQYVJh2B\nvE1F3r0whjcKPDevdY6eH8WXf3gU7QP2xR7KnBE8yXkSLhsqdACAvjFXwa/tC0TAAFDJyZN83XOy\n3YJ3L4yhrW9+ThaL3Y9vP3MKHbM4+fjkifZBx7yMgSCWGj95sQ0/e6Udbf12vHJ8APF4/rqt/Dm7\nrp678VeXaFBhUuPCZRuOtY7hqV+14r3WcVSZNdj9sRVZX0easFTEkiJLoUgMchnlaRNLG2OiPJhe\nI8OKqiLs++RK3LWzAS2NRuGYUoMS0Vgcdnf2WrouXxjPvtGFI2/3IhBavIDSfOANcN7saIzFgde7\nEE7kHyw1HN4QpBJRRiGbzLRIdhf82r5QFEq5BCLRzGpBmfI6kiGRvMzgt1g9gUieIwvjt+8PYMTq\nxcmOyYKf4/BwF6f+MfeiRrQJYrEYGHdDr5FhU5MJvmAU/RO5L+gsy+JSvx06tQzVpVydXIZhsKOl\nDNFYHP/xWicu9duxvrEY3/ri5pw+OnFCJEdjqZ5kKv9GLHUqTGpIxCLcvL4CIoaBUafAZz5Sl9J9\nbdqXnN1y8fbZEURjLOIsi97RwiOSs8UfjOKJw+dntasaZ1kMWTwFt9d+6VgffMEoyowqTDoDePn4\nwBxHu7g4vSHoNbKsZS95GsrnIJIDkaxi+BM3VOd8LonkZQa/KvbMwq+TjSlXACfbuZN70FJ4WSK+\nbWgszqJ72HnF4yCIpUQoEoPbH0F5sRrb15YBQN6dnQm7Hy5fGKtq9BAl3SQ+cUM1vrFnE+771Cr8\nrz9ag6/evT5v5EMqiGQukhyLxxGJxsmTTCx5DFo5nvjKR/C5m+uzHjNd4SJzclckGsPb50aF/+9a\nwHvU2+dGcKnfjtc+GCzo+ClXAD84dA6P/ceHOJo0xmxY7H68c24MpUYV/v7eLSjWKfD6ySFYZpnY\nttjE4nG4fWEYciTt8agUUpQZVegfdxe0QwcA4Ug8q93MVDSzxGYydNVcZggi2X/lkeQ3Tg0jzrIQ\nixiMWr0FJwY4vSHhRt8+QJYLYnlgcwULqs/Jb/MWFymwps4AEcOgrX86+S4ai+NyWvSqZ4T7/5XV\nqY0kxCIRVtUasHNDBbatLcu4XZiOWMwI7wMAoTD3XwXZLYhlgFYly3ke5Iskf3DJAo8/go9troSI\nYdA1tDAiORSJ4Y0PhwEAQxav0CUzG95ABP/wn6fRmRjPxQIsk+0DdsRZFp+6qQYqhRSfv3UFYnEW\nLx7ru/IJJPH6ySHsfvgVHHyjC7ZZtoQuBLcvApbN70fmaazQIRiOYdxWWHGASCw+58o+JJKXASOT\nXqGjFp/Fmd5MYLYEQlG8e2EMxTo5tq8rQzTGYtSa/wcZCEURCMXQXF0EiViEjgX0Jf/2vX788Mj5\ngrelCOJKeOrXF/D4s2fyRi/4m4ipSAGVQoqGCh36xtxCGaK3To/gewfPoGto+tzgb9RN1VfebU2S\nZrcQWlJT4h5xHcCXRmwfcMzoPAkAJy5xibB3bqtFbZkG/eNu4RzJxYjVi9+8149LBebnHLswBo8/\nglIDF6k8123NeXzHoAPeQAS3b62GWa9A97Az772N3+GtT1gQtqw0o7ZMi1Mdkxiaxe5vPs73WBEM\nx/D22VE8/tzZeb/nTle2KEwkz8aXzLIsotE4pJIFFMk2mw27du1Cf38/Ojs78fnPfx5f/OIX8cgj\njwjHHDlyBHfffTe+8IUv4J133gEAhEIhfPWrX8UXv/hF/NVf/RUcjsWPKk45Ayn1Q5cyU64AfvzC\nRXz7F6fw66O9AJIjyTMvDoFQFP966Bzevzie97UHJzwIR+O4YXUpGhM/yEIsF3zSXolBhaaqIgxP\nemc0NpgvTndNoq3PjvFZFhYniNlidQYwavXB7Y/kLW04xUeSdVyS0bp6I1gW6EjsqvAWpIGJ6fOp\nZ8QJtUKCCpP6iscqSYsk83kB5Ekmrgc0Sim2rDRjxOrFo784heFJr/C3cCSGy6Nu1JRoYNQpsLLa\ngFg8vy/5v17vxLefOYXfvNePg6935R0Dy7J448NhyCQifOWuFjAAzuQRyZ2JgNINq0vQXK2HPxTN\nG5ganPBCIhahvJhbGDAMg7s/2gAA+PXR3nnROizLYtjqRaVZjY0rTLC5g3mj4rOlkBrJyTRUFAEA\n+sbzi+RYnAULLFwkORqN4tFHH4VCwV3wf/zjH+OBBx7Ac889h1AohHfeeQdTU1M4ePAgDh8+jJ//\n/Od44oknEIlEcOjQITQ3N+O5557DZz/7WTz99NNzGuR80TXkwDf+7QROzSIJ7Vpl3ObDd/7jQ5xN\nnHj8Fq8/h93i6PkxdAw6ChLJ/IWlpkSDujJOJCff1LPBi2SjVo6WBi5L/1xP7ovDXOHfq4d8z8QC\n09Y/HT1Kt0qkkxxJBoC1iZJubf02sCwrXNh5sW13BzHlCqKpKtWPPFckaZ7kcIS3W5BIJq4P/vpz\n6/AnOxvg9IbxuyQ/cM+oC9FYHKvruJbVzYmdm1yWiylnAO+eH0OpQYnaUi0mnYG8lgNvIIIpVxBr\n6oyoMmuwoqoIl0dcOWv7dg45IJeKUVemFcaVK6cnGotjdMqLKrM6RQCurTNida0BbX12HG+byDnO\nQphyBREIxdBQqUdTNSdOhy3ePM+aHYXWSOapNKshlYjQX4BI5q+DCxZJ/ud//mfs2bMHJSUlAIA1\na9bA4XCAZVn4fD5IJBK0trZiy5YtkEgk0Gg0qKurQ2dnJ86cOYOdO3cCAHbu3IkTJ07MaZDzBX9z\nuzyycNmsVwOXN4Qnj1yALxjFno83gWG4kxKYjiSn2y0i0Tje+JCrCTlk8eZdYfIimS9DJRYxGMyT\noQ9MC1eDVo6tK80AgNNd8y+Sw5GYUAe2e4RE8nJhwu7H3//8JAYLWJDN6fVtPrzwbt+sq6609U17\ninvyXD/4GygfSa4v00GtkKAtUT+c31kZS/jp+Bth8zxYLYBpkRxL2C34uVJLauJ6QcQw+Mz2Wijl\nkpQdUL6O8Jo6buHaXF0EBrnF6Lut42AB3Lm9Dh9ZxyXitg/mtlxMJiKtJQmrxZZmM1hwtoVMuLwh\njNv8aKribIp8bkKupMKxKR+iMRa1ZdqUxxmGwZ9/ahWUcjGefbMbk1fYfZDXAvUVOlSbNSmP5aJ/\n3I1THZaCotmOWdotJGIRDFq5UFs5F7ztbEEiyS+88AKKi4uxY8cOsCwLlmVRW1uL7373u7jzzjth\nt9tx4403wuv1Qqud/qJUKhW8Xi98Ph80Gu5DVavV8Hrnd/UxW/h+3+P2pd0J7sDvuzDlCuJzN9fj\n9huqoVZIBcEYCHHeKm8gkuKd/ODSBJzeMBiGizbnWwkPT3LbOGXFKkglIlSZNRie9OVN3uPLvxm0\ncpj0StSVadEx4BBE/HzBrzwBiiQvJ1ovT2Fsypd3a3KuvPDOZbxyfAAvvttf8HOisTg6Bh0o0Suh\nVkjybs1OuYMQMQwMOu6CLxIxWFtvhN0dwvGL05GdsSk/WJZFd0J081GaK4W3W0T4xL2E35IiycT1\nBMMwqC3VYMLmFxaKHQMOiEUMmqs4EapSSFFdokHvmBuR6Exfciwex3utY1DKxbhhVYkQge7Mk2sz\n6UgVyetXcI1/LmVJZOfF8Kpa7vXNeiX0Ghm6h51ZRSYv/vlGKsmY9Ep86faVCIVjOPw/l3OONR+8\nt7m+ogjVJZyeG7Hm13LPvtGNf/vNJTz9UpuQK5UNp4cTu4YCE/cAQKeSweuP5PVHR6LcdZC/Ls6W\nnOnOL7zwAhiGwfvvv4+uri5885vfREdHB37zm9+gsbERzz33HB5//HHccsstKQLY5/NBp9NBo9HA\n5/MJjyUL6XyYzYUfWyhTiSinxREo+PUnbD68eWoIn7+ted4jMXOdY9+4G2XFKvzF51rAMAyKNDL4\ng1EYjWrhhsiygEItR1FiZfbW2VFIxAw+ua0Or77fD2cwitVZ3j8Wi2PM5kNtuRZlpdyNe1W9EYMW\nD4JxoL4s+7gDUe4H21BrhNmsxa4t1fjPV9txedyD22+qndN8M2FxT4tkmzsEVixGSSJhY6FZiN/m\ntcJiz82RsAnZPKEFGUtbosXzH84M485bGtBYlT9629Y7hWA4httuKMOE3Y/THRZIFFIYEo0N0nF6\nQijWK4RzBwC2r6/AqY5JvHVmBACXxe30hCCWS9Ez4oJcJsbWdRVzjnbwmM1aGPTceaBSyWA2ayEb\n5XaATAbVon+/V8pSH38hLOc5Xu25raovRueQE55wHAaDHIMWD9bUF6Oqcvq837iyBEPH+mD3R7Gu\nMfV6cCoRXPrUR+pQValHZUUR9Bo5uoadMJk0GWv6ms1a+MJjAICmumKYzVqYTBqY9Ep0DTlRXKyZ\nUZ1j4ChXjWLb+grhM1q/wox3z48iDAZVGT43q4u7B25YVZrxc/2jXRoceecyJp3BK/rcJxMBtYbK\nIhh1Cug1coza/Hlfk/ctn+myYnjSi6/csxGbV3GOhLEpL577XSf+6q710Kll8CcKDzTWFUOZp5kI\nj8mgxOVRF5RqBXTq7DaNWKKGtlYjn9PnkHM0zz77rPDve++9F9/5znfwla98RYgOl5aW4ty5c2hp\nacGTTz6JcDiMUCiEvr4+NDU1YdOmTTh69ChaWlpw9OhRbN26teCBWa3zu93KsixGEisimyuIoRFH\n3i+DZVn8y3Nn0TPigk4hxkfWlc/beMxm7Zzm6AtG4PKGUVuqxdQUtzBRSMWYsPkxNJoaUe0fdqDS\npIbDE8KwxYMNjcVortThVQBtPVasyCJ2R61eRKJxlBtUwhhNiRXexe5JaLLUWzWbtRibTMwpEoPV\n6sGqRHTs7dPD2NhgzPg8ADjeNo5Db/UgFImh0qTB3+3bDKkk+6Kkf4RbkZfolZh0BvDBhVFsT2yF\nLSRz/d6WAtfC3AYSUdqBMde8j8XtD2PY4oFBK4fDE8KPfnkOj9y7Ja8P+L1znLBtKNdCKmZwugM4\n1TqGzc3mGcdGY3HY3EE0VRaljL8mkZDnTbRHvXFVCd74cBh/ODmIUasXG1eY4LjCHS7++/P7uZun\nwxmA1eqBNXGdiISji/79XgnXwu9zoVnOc1yMuZkTuzkXOi0YGnWBZYGmCl3KOKoT5+bJi2Mo1aVG\nMl97nxOvNzabhec0VxfhVMckLnZZUF6cmmjLz7E/YQGUM6zwvFXVerx3cRxnL40jGoujfdCBO7fX\nQsQwONc1CblMjCKFWDi+poR77VOtY5BvqMDghAf+YASrE1aRzgE7RAwDtYTJ+rkqZBJ4fKEr+twv\nDzuhVUlh0MphtXpQaVLh0oADg8OOrDXb/cEIvIEI1tYb0VCuw6snBvHoz05gz21NuH1rNX79Vg/e\nPT+KpkoddrSUw2LzQSmXwOsOoFC/gTzhMe4fsudMeLYkcj9iCU2SiVziedZhi3/6p3/C//k//wf7\n9u3DoUOH8OCDD8JkMmHfvn3Yu3cv7rvvPjz44IOQyWTYs2cPenp6sHfvXvzqV7/CAw88MNu3mzc8\ngYhgSQBQUEWEDzsnBf9hcuJOPnhrykLAW0bKkqKmaqUUsTgrZIjy8A1F+DIpjZVFqElszQzlMN4n\n+5F5+DI21hxdjAAuiiaXiqGUcwK3RK9ETYkG7QP2nO0yz3RZ4QtGoddwq/03T4/keR9ubjeu4Vam\ns/UlW+z+vFtAxNVnPFGHeNIRKLgud6F0J5Jzdm2qxNaVZvSPuwvqtsVvazZX6bGiklv0ZctrcHhC\nYFmuRnIyBq0clWbuQl5hUgsljH5/issT2LCieA4zyowkETlJt1tQdQvieoO3IgxaPELXu7X1qcGa\n5kQgJz15LxKNo63fjhKDEjWl0/dC3s+cqwfApNMPsYhJuQ6sSVg1Wvts+OlvL+HFd/vQ2mtD/7gb\nFrsfa+uMKZ0DhWtN4hr1/37Thh8euQCHJ4R4nMXwpBflJlXOHW61QgJfMDpnPeIPRjHlCqK6ZDpq\nXl3Cfaa5LBdWJxd9LjOo8Cc7G/Dt+7ZCJhXhnUSDlK5h7rPjG4/ZPUEYdYVbLQCuXjaQuZJXMvx9\nZK67dAVXlz9w4AAAoL6+HocOHZrx9927d2P37t0pjykUCvzoRz+a08DmG15c8j+acZtPuFFlIhSJ\n4cjblyERM5BLxbjUzxXtLiT7/IV3+/DBpQn8w/6bCt46KBS+mUGKSE6s5qwuTsCKRQxicVZoTd03\nxp1kjRU6FKllKFLLMDSZfWUpVLZIujCYeZGcp/SL3ROCQStP2YZqrtFjaNKLgQlP1uSkSWcACpkY\nj/75DXj4px/gleMD2NFSjqIs2yh8guCGRhPePD2C1l4bogUWDHf5wvj2L05hU5MJ9392Xd7jiauD\nPxgRktpicRaTjsC8lETj4W+CK6v1qC/X4nSXFafaJ9GUsFx4AxE8+otTuHN7LW7dXCU8b8oZhEYp\nhUohQUO5DmIRg9Y+G+75WOOM68GUa7qRSDot9cUYtfpQX65DRSICxXsX1zea5m2eEklq4h7VSSau\nV8qMKsikIrQPOOD2hVFlVs+472tVMlSa1OhNVL7g7yFdQw6EwjFs3GBKuZ/xYvdUhwUf31KFTFgd\nARTrFCmid3XCb/zq8QGEEz7Zt04PC13mdm2qSHmNSrMacpkYl0ddmHQGhGvF0fOjqC/XIRSJob4s\nu4YBAJVCglicRTgSn9P5zwvhmpLpSCsfPBue9Ga9n/M6waznroM1pVqsrjHgQq8NQxaPUB3D7g4K\nvRWMWexr2dCqpAAAd57GaYIneSHrJC8HeHHJ34zyRZJPtE3A7g7h9huqsbHJBI8/UlDZk0mHH6+f\nHILNHSooQ79z0IFnXmnHobd68hYbT55HaVokGeBu5gBn2gcgCI6+MTcYAHWJguM1pVrY3aGsyXS8\nSK5KiiQX6xRgmOms3UyEIzF4A5EZ5nt+RZyt8HecZWF1BFBiUEKtkOKzN9cjGI7ht+9lT67is2GL\nixS4ZX05HJ4Qjl0Yy3p8Mu39di5K0GcvuK0lsfDwUWT+JlVoN6VC6Rp2QCYVo75ch9W1BmiUUnzY\naUEszl1Eu4edcHhCaO2drmQRZ1lMuYKC6JXLxLhxdQnGpny4cHlqxntMl3+b2er0xjUlEIsYbGwy\nodSoAn/frSnVzCphJR8z6yRTJJm4PhGJGNSUaOHwhBCLs7h1S1VGH3FzjR7haBw9Iy6MWLnqT+cT\n5/eGFakLWFOREusajOgZcWW8xwdCUbj9ESFpj6dIw+0mhaNci+S6Mi3aBxz4oN2CUqNKiFDziEUi\nNJTrMG7z43TndNnad86N4vD/XAbDcG3rc6FWcNqAb2Q0WzLtKieL5GzwATuzfvozWJcoCfvCu33g\n77p2d0goXzvbSLLuKkWSrzuRvLmZF8m5b8DH2ybAALhtSzXW1XNfbnJr2Wy8dKwfsYTwGspTJsXh\nCeEnL17E+20TePP0MJ5+qQ0ubyjncywZIsmaxInAr954a4THH0YsHkf/hBsVZrUQ1eYjxKe7JjGV\nJHr9wQhefr8f3SNOFOvkwgkGcD+wYp0ip0jmBYIx7YbPr9x7xzJvUbu8YYSjcZQk2ol+dGMFtCpp\nilhJx+nhWl/rVDLcub0OMqkILx8fyGnp4OE7JvlD0YIapBBXB363Z11iOzRf047Z4A1EMGL1YVWt\nAVKJCGKRCDesKoHbHxEizHwd8OR2ti5vGNFYHOakyPCnt9cBAF45PjhjG9OW1kgkmboyHf7t6x/F\n5ouPTzAAACAASURBVGYzpBKR8HvfMI9RZGDabjHdlpqqWxDXL3yJNKVcgu1rMuet8CXX/vXQOXz7\nmVM48PsuXLg8BaVcgqaqmVVnbtvCidO3zgzP+Js1rfxbMmtquWvbHTfW4M7EdSQWZ3HrpsqMu9R8\ngOmNhC1r4woT3P4IJux+7NpYmRLIygTvGZ6rtZDXSck7emXFKkjEDAZy1Ci2pgXsAKAlkZOUfF+3\nu4OwJZLwjRmumbnQ8ZHkPM3KIgtdJ3m5wN+Am6r1UCskGMsRSbY4/Lg86sLqOgMMWjnW1hvBAGjL\n00t9yOLBB+0WISo0nEOAsSyL/3itA75gFLt3NeJzt9QjFmdxrDV3o48Jux9ymTil6DYfSZ4WydzN\n1+OPYNTqQzgSF7rmAdM+rQOvd+Eb/3ZC8Dw982oHXjzWD7FIhLt2Ns54b7NeCZc3nLGFZygSw0tH\nuVIzhrQVYbFOgSK1DL2jrozeKL6OIy/uJWIRSgzKxOo/sy/V4QmhSCODSMSgSC3DbVuq4fSG8XbC\n85QNlmVT2ormK+WTiUKEODF7+IXspubCdntmA+895qMZAHDjas7PznsVBxJ1wKecAeF3N5WIiCRf\n7CtNamxp5jzN7Wm/H/6mksluASBl+7UyceNZP49+ZGB6W3FGW2qKJBPXIXUJkXxzS3lWy8HaeiNK\nDUpUl2hQalTh6Pkx2NwhtDQYM0Yg1zUYUWpU4WS7ZYZIE8q/6WeK5E9vq8HujzXijptqsKnJBLNe\nAblMjB0tmcX7ioRAd/sjMOrk2Hsb1xdBKZfgc7fU5527KhEYm2skmQ/KJQt+vo7z0KQ3JciWDK9F\nTEnXwRKDSvhMJGIGpQYl7J4g7J7MwbV8aNV8JDn33KKJiltSiiTnZsLuh1ohgVYpRVmxCtYciUEn\nEl1q+MLhGqUUdeVaXB515WxC8PpJbrV37ydXQiYVYTCHPePouVG09duxrsGIO26qwW1bqiGTinD0\n/FhWC0CcZWFxBFBmUKVsGfGeZN4PWWqcjiTzFge+jSMAbGwy4e6PNmBLIju/LyFeu4acMBUp8IMv\nfyRjpQj+REk/MaKxOL574DReOz4As16Bm9eneqsYhkFjZRGc3rDgJU7GkuGiUqxTIM6ycGUoFh5n\nWTi9oZQt6jtuqoFcKsZbp4dzWihGp3xwecOCP6xjliL5XNck/vqJo0u+Ic21yLgQSS6GTCIqOJIc\nicbydsHjf3flSRGRpmo99BoZznRZEYnGMTDOLWpjcVbYFeHPKXOa6L1jWw2A6WsFwN0YznRZUWpU\nZbxBpvO5W+qx7xPNaCjP7SucLel2C/IkE9czN60pxRdvb84pKtUKKb7/V9vxnb+4Ed/64mbh/N24\nIvMuj4hh8PHNlYjGWHzYmdrB1+LgheXMkqRFGjk+dVMtZFIxRCIGD31hE/5+3xaoknZtk0kObq2p\nNcKkV+LLn2vB/75nvZC4lgt+N3iukeQJux96jWxGbtXWRCm3bI3CppwBaFXSGc9bl4gmN1QUodSo\nQiAUw1ii9fbsI8nc/NMbp6UzbbeYW53k60IkR2NxWJ0BlBVz4rK8WC0IznRYlsWJSxOQSUUpJZ5W\nVOoRi7NZe6m7vCF82DmJCpMa6xuLUW3WYNzmE0zj6VxKdPC6a2cDGIaBSiHBtjWlsLmDWStp2N1B\nRKJxQQTzCJFkPupVpAQDbvU5LZKnTzaJWIQ7t9cJF43RKR9cvjD8oShqSrVZkw35C0e65WLC7seI\n1YdNzWb8w/6bMgqERsFyMXOLhl95J/us+UjcVIamJ15/BLE4m9KdR6OUYvu6MtjcoZw2jfbEZ7t9\nbRkqTGp0jzhnVUWhc9ABFtPZucT8MWH3QynndknKilUYt/sL8oy/8eEwvnfwTM6FC38hLUr6zYgY\nBjeuLoUvGMW7F8ZSPPr8tYFfEJrSftP1ZTrIJCKMJFmqXjk+gFicxR/vqJtRBzUTVWYNPrY5s0fy\nSuDtFtMd9yiSTFy/SMQifHxLVcFJ9EVqGb6xdxM+f+sKQQxmYmUNF2gZTSS3RWNxTDr8wrXDnMFu\nkY5Jr0SlObtlQqWQCjtOfMLglpXmgrtz8nYL3xxEcjgSg80dSrF28mxuNkPEMPiwcxKjUz58/9kz\nQtfCeJzL4zBn0AEbm7hFx9p6oxA57kkEOGbrSdYopWAwXcUrG5S4VwDDk17E4qzwZfM/utEMJUzO\nX56C1RnEluYSKGTTJ1VVonzTaJbo1tELY4jFWXx8cyUYhkF1qRaxOJs1GjZs8YABhCx3APjoxkoA\nwLtZEtAsdu7kS//RahIiORzhfgxqpQRqpRQ2VxAXeqegkktS3oen1KiCWMRgzOYTxllhyt6Qg//R\np5eB46N0axuLs96IeZHePmCHxeFPWTxMOmZu6fCeTt7jmen9DGktLD+2ifv8/ufsCOJxVkgISKYt\nYbVYW2/E6hoDwpF41oRCHpsrKOwg2BILEf67IOaHWDwOi92PMqMaDMOgoliNSDSe0wPPw3uJe3KU\nAfT4OAGsT9vSu2lNKQDgt+9zSaI1CY8fv81oFRLxUqMcIhGDcpMaYzY/YnHu5vj+xQmUF6tw0+rS\nvGNeSMTpHfdIJBPErDDqFPjkjTU5k73KjEowDATr5pG3L2P/P72J91rHwQAo0c8uMpqNjU0mqOQS\nrKnP3mcgG/wusz80e5HMi/1MIlmrkmFVrR7942788PB59Iy4BN3CJ0lmEsnr6ovxrS9uxh031giR\nY74gwmztFiIRA41K+v+3d+eBUZVX/8C/d/aZTCYJ2SGQsIRVUHYUTVFRcUFUQEMwuLZoF+gLtUDV\nUrEu6BuXtsKL0lpZZKnGirbVX1FBQTZxYTMgJLIECNkgmclk1vv7Y+bezExmJpMEsky+n3+EkMDz\nmMydc889zzlyF69Q5JpklluE9ol3ytWoAZ67wl4+vRN9udxuvLPlGAQBuPVK/+lw0t1esN6ATpcb\nW74phV6rlMsUpMNxJ0LUJZ86V4ukeJ1fj8Pe6SakdjPg4I9VQbObwdq/AQ0vBIlBq4IpRoPKmnrU\n1jkwcVRG0MyWVPt7uqJODv6DBdOS5BCZZCloDfaikGSlm6AQBGz99jQWrdiJuX/6Ais2HUR1rQ3n\nqq3QqBV+7d6kILmqph52hwvrNv8gBy7ynPdY/8dNPVOMyM6Iw4GSKjyxchd+s+xLv/rj6lobio5X\nIyM5BgmxWnkE6MEwPbAt9Q488dddeHvzDwAaMovSIzW6OM5VW/1uZKXDMq+9tx/f/lCB59fsxZ/f\n3Re0pl26wQt3CDNYJhnw1Csmx+vkujYpaG6USQ5SY5yRHAOny42yKiu+2HcGblHEbVdFlkW+lKQ3\nA5fU3cLhgkataPd1EUUTtUqJ5Di9fA7h++PVUCkVSE80YPSglLDDsJrjzmv6oOAX4+XyguYwyOUW\nza9JDtYkwJcUT0nv/0UnqiGKYqP2b4H694yHWqWQM8duUUSsQd2i/18mg6bJg3tOHtwLr7rWhl2H\nypCeaMDQvp4DMg0BrH/Au33/WZyprMM1w7o36s8qZViDlVt8+nUpzpvtuOqydDn7LPUVDNbhwmz1\nTM0LnNYDeB6p2OwulAQ5OSoPEkkMCJL1/vVMeq2n9hrwBNA3ju7V6O9q2FcMrDYnvvc2Rg/Xl1bK\n9AYGyVLGNjFI2yuJVq1E7vX9MHZwKq66LA1GvRq7DpVh9ceHUXbeipR4/zprqdyi8kI9vj1agf9+\ndRL/2XUcAOShKcHaZl07wpNNlm4o9h1tKL34f3tOwOkS5d6Wg7MSoFIKcqufYI6VXoDN7sKJsw3T\nGgEELdUJVHHeijf//X2TL2Jq6GEsPXH4yfAeuH5EBkrLLfjTu/tw5NQFfPNDRaNyHc8jTs/34scw\nLRelNkGB40sFb8mFRPq1dBNUcaEecUZN0At4hs+N8+ET56EQhJA1jG1J6Q2Snd5SFbvDxSwy0SWQ\nnmhAbZ0DVTX1OF1hQXbPeDzz03EXtf++QiG0+DxBTCvKLc4EaTfra8SAZBi0KowemIKR/ZNRVWND\n+Xmrz6G98OUmvh2AmluPLIk1qGGpd4YtmXQ6u2gLuBqLHY+/sRPbmugG8cneU3C5Rdw4uqfcYiVG\np0ZSnA4nymrlzJRbFPH+thJoVApMubpxgb9Oo0JSnK5Ricbxs7V4Z8tRxBrUftnnjOQYCELwTHJD\naUOQIFk6UBZkmk/RyWqoVYpG2V69VgXfska9ViWf/LxpTK+QoyOBhszxgZIqCELou0bp7zXq1XJ7\nF4k0NSewbjPQxFE9Mfv2IXj4tsFY+siV6JcRh2+PVsBmd8mdLSTSC6iipl7OEB4s8dyphiq3AICx\ng1Lx8zsuw9MPj4VKKciP4M1WB7Z8exrxRo08XlyvVWFQZjecPGcOOSTlWKknKCu/YIUoinJmscZi\nhzXMIyxRFPH3j4rwxb4z2HHwbMjPC2S2OvD1kfJLNrGxo5Lq8KWDHQpBQN4N2Zj6kz4YkpWA6dd6\nuq189rX/JMYybwYa8GSj6+qd2F9cib0BB0pq6xyI0amCXiil8oiUBD0S43QwGdQ4V+XpcFFVY0Ny\niIu9FCQXn65ByZkaZKaFrudvS/LBPWdDn2QGyUQXn3QQePf35yCKQL8Ia4XbSkMLuFZkkhODxwQm\ngwYv/XI8HpkyBIOyGg7CB+uRHEyCb5Dcwj7x0uHFUDMfgIZyiy4XJO/6vgxnKuuw9/C5kJ9TV+/E\nlm9KEWtQy50qJL1SY1Fb58B5b/eEU+fMqK61YfTAlJCN/TOSjaipa5gK5nC68X/vH4DTJeLh2wb7\nHSTTqJVIT4zBiXPmRoePpMcz6UF++Ab0SoAANGotVXmhHqXlFgzKTGg0hlIhCPIpVqVCgEalwLjB\nqRjRPxkTRwWfCCSRRuU6XW4kx+vDjrgEPD/4Feet+OZIuXwDUF0TespYKIIg+N2MBPaU1GtVMGhV\nqPIZylJZU49z1VYUe7PswV6EgiBg1MAU9EiKQVaaCSfKzKi3O/Hp16dgs7tw05hefo9dpHZj3/xQ\n4clKBgTL0rRCq82F6lr/ASznwmST9x4ul8eWBnsqEIwoilix6SD+UrhfPgTRGblFEa8V7pcz/01x\nutz4/ngVkuN1cvtCwPO9vPXKLMzPHY5JY3ohrZsBe4rO+TWPP+O94ZR6AB85dR7L/3kAf/3XIb8b\njZo6e8jT4D2SY3DzuF64fXwWACClmwEVF+pRfr4eblFEUojHhtI5hS8PnIXLLWJAr47xBim9Gfj2\nSWaPZKKLT3oP3+lNhPTt0bincntqGCbS/Ezy2SrPaO1gpWYSjVoJQRAw0HuI8bujldhxoAxKhdDk\ntFTfJFdLM8lyh4swT2ul80/qrtbdYs/3nuA41EE6wPN4vc7mxI2jezZ6XCqVXEhZSulxr1SnGkyP\ngMN7nkNoVky4ojuG9mnc67RPdxNsdlejNZ6u8NyhBav/NerV6JUWKz/ml+w75ikJGNY3eE9V6bGK\nJ6ssYET/ZPzyrqF+hw+D8V1DuHpkSWo3PVxuEX8u3I/n1n4Np8uNqlobYnSqJv+tQIMzE+Q+kMEe\n6STG6VB5od5vqtHn+07jUEkV+vYwNZm5zu4ZB7cooujEeXyy9xRidCr85Ar/9nTD+yVBgKdX7tK3\nv8bvVuyUD/K5RVEOyAHIgauUtQ9Vl2xzuLDh0x+gUgrQaZRNHgyUfHesUq6P3lfc9OAaidPlbnGL\nn0iYrY4mpxr5OlFWi71HyvHhl8fhcDbdU7r4dA2sNpc8tCcYQRBw7XBPyyXfp0fSU5mRAzydaN7d\ncgz1dhfq7S75hsbtFmGuc8jN54P93dMn9JOfMKQm6D0/N94b1VCPDU0xGhj1avnfGdjRgmR3Q5/k\npm5+iaj5pPdMqayyb0bHuAZIdBolFILQ7PcHURRxtrIOKQl6v97uoaQnGhAXo8G3RytQWVOPSWN7\n+Z0xCkatajiH1NzOFpLYGM81PdzhPalffJfqblFVUy/3Ra3w6Tzgy2x14L9fnUSsQR10vrp0eE+q\nNS064XlDDJcNkoJk6fDed95WY+OGhGgE7r2rDOzh2pBJDh6UDs5MgMst4ojPaX3p3woZJHtrkPXa\n5r0Z+o7HberODwBuGZeJG0f3lG8AzlbWobrWhoRmzl0HPMHJzIn9MTgrIehNRqJJB5vDBUu9U56a\n9PGukxAB5AT0Yg4m23vB2vDpUdTWOZBzRfdGgXycUYu+PeJQfLoGx0pr4BZFfOydbnSmwgKrzQWl\n98CTFCRLzenLqurgdLkb/fztP1aJyhobrhuRgeyMeFRcqI+ol+P6T36AQhCgUgrYfyz84Bpfb3xw\nCAtX7Ahb/tEar77zHea/9iU+/PLHiNrl7fcO3bHanNgXsI9gZSRyqUUTp7fHD02DRq3A5r2n5HWc\n9r6WrvK+Bn1vSKX2gWarAyIams83Rcpmf7HPc1o7sEeyRBAEOZssCA0/b+1N6VNu4XaLcLlFaFr4\nBkFEofm+h6tVCr/xzR2B1F62ucNEaq0O1Nmcfk/2mvp3pNgpKU6H267KiujrpOC4WwviB8BnNHWY\nTHKXPLi325tFllqfSZlZXx/vPgGrzYVbxmUGzXBm+nS4cIsijpz0DNIIV2yekeR5AZSWWyCKIvYd\nq0CMToW+PYIPA5CD5FONg+RuJl3IWmGpvkea8Gd3uFB0vBo9kmJCrk96rGLQBs+WheI7Hjdc+zdJ\nRrIRuddnY5y3C8CRU+dRb3e1+E4wMy0Wv8kdHrTExbewf/TAFCTFeQaMaDVKjB4Uun+lROqQUFZV\n523+Hrz0ROqHPTw7CT1TjNh7uBwVF6zyIbEh3uDtiPf7KD1aKqu2Ytl7B7Do9Z1+weN+bxZ4zKBU\n9E73/JyVNJFN3nu4HOeqrbh2eA8M6JWAU+XmoINXApVV1WFP0TmYrY6wXTpayi2KOH62Fk6XG4Wf\nF2PZewearJc+6JMF33XI8xiy4rwVy97bj7l/2tbopvFgSSWUCiHsUxzAc1J7whU9UF1rw5feIR6n\nK+qgVSsxoFeCXA8s3dRIdebSDUqkp8OlWuMS73CRcKNfpc/NDNNfvK0pBAFKhQCn2w27N5PPTDLR\nxWfQqRDnnX6bkWyUD812JAatqtmZ5KbqkYMZPTAVKqWAWZMGRHwGQiqzSGzxwT1poAhrkv3sKToH\nhSDghtGe+emlFY07SOw6VIYYnUrunRso3qiByaDGiTIzTp0zw1LvbLKmMC3R01e4tMKM0nILqmps\nGNK7W8jHEWmJBsToVPJIXACotztRWWNDz9TQb7wDesYj1qDG9v1nYLU5UXSiGnanW+7OEYxRL5Vb\nNP/NUOobHSqzHYx0xywN7mhp4X04vjXOmWmxcrA6dlBqRKUdMTq1nP0fNTA5ZN3T9SMz8Ku7huLR\nOy7DjaN7wi2K+H97TsrBnHRDID3az86Ih0IQsO9YJb49WoELZrvcz1kURRwoqfJMaUyLlbs1NFWX\nLJVuXJ6diKHefR4oabrkYvPehoNs4bp0tFStxQ6nS8SQrAQM6BmPb49WhD2IWFfvxNHSGvTtbkJ6\nogHfHq3Ev3b8iMdX7sJXh8thtjqw/J8H5MC1ts6OH8/Uom93U0RBpqd3qYB/7zgOh9ONs1V1SE80\nQKEQkOl9TUklNVImWWrvFhui3CLQsL6J+NXUofjV1KH4wwOj0TvMRDwpgJZunDoKlVIBp0uE3dm6\nLAoRhZfuLRWUnjB2NJ5McvOCZLmTVpiD/IFGDkjGsnk/CVs2F+iKfknolWKU36ebyySVW4R5Uut0\ndrE+yWarAyVnatC/ZxwGyRNv/Gt+bQ4XKi7Uo2eKMWQGRRAE9EqLRWVNPd7ZegxA0290KqUCPZJi\nUHK6Fhs/OwoAuDxMyyeFdxzzufNWXPA+DpBak/VMDf2CUquUuH5kBupsngNn72wpBgB5jHQwUia5\nJdmsm8f2wi3jMuWShkhIQbI01jnUYcfW8M1OZ6bGIufy7uiVasRNY3pG/HcMyeoGAZBvqIJRqxQY\n3j8ZKqUCYwenIs6oweavTmHbvjPQqpWNvsdJ8TokxeuCHuI7XWFBda0Ng7MSoFAIcoBV3ESQLHfs\niNXJN0NS2UIodfVObNt/BgmxWsQbNdh3rBIud+TTAyNR4Q3+eyQb8dCtg6BVK7Fu8w+4YA6e5f7+\neBXcoojL+iRi3OBUOF1uvLu1GHqNEj+dPBh35fRBda0Nb2w6CFEU8b13guGQIOU2wSTEanH1sO44\nd96Kv/7rEJwut1wmNOXq3rh9fBZyLg8Mkj2vvUjGuAKelkvDs5MxPDtZLssKZdSAFORcno7rRga/\nGW8vKqUAp8sNu3ckNcstiC4NqcNFc94/21KMTuV3LYjE2ermB8lA87O144em4w8PjmnxU7iIDu51\ntUyydIirb484uTwgcKqd9Kigqczo5KuyYNCq5LKGARG0b7n3xgFQqxRyy7RgtbS+pNOuUjZZmi7T\nKy10dgoArhuRAY1agcKtxThVbkbO5d3DnpyVapINLfhh69sjDtMm9JVb5EXCoFMj0aSVT4629HRq\nOFImOSlOB6Nejd7pJvzhgTHNynjfmdMHSx4ag77dIzt1rFIq8PCtgzFmUAr69jDh5rG9oNeq/A4h\ndIvVyrVaGrXnJST9zEmBrfRzEWvQIDleh5LTNWHLFKQguVusFmndDEg06XCopCps0PvlgTOw2V24\nbkQPXJGdDLPVIbesC+U/O4/j+TV7G9UWV1ywysMnfFXVeNaVaNIhKV6PaRP6wlLvxKbtPwb9+6X9\nX9anG666LB1GvRrDs5Ow5KGxuHJIGm65MhNDenfDwR+rcbT0gvzaa6oe2dct43oh1qCWy66kIHlA\nrwTccU0fueuJb7s+oHGP5IvBoFPh/psHNdkTtK0pvZlk6fXJcguiS2PMwBRkpcU2GQu0F4NPh4u6\negfcPu9Dod6TWpJJbg9G79PBcC3gnF1tLPWPZz1BQO90Eww6NRJitY27R4RpseYrOyMev79/FPp0\nN2FQZkKT3RIAoF9GHOZOGwaNSoGBvRLkuuiQnx9weK/EG+Q3dcjHqFcj5/LuEAGkxOuRe32/sJ/v\n292irfRMabhzvhSZ5NQEA1RKQe6A0RJatVKelhipIb274ZEpl+Hx/FG43dumTgq8dBol9FoVMtNi\nIQC465o+ABoyyQe9JRJDfIK+3ukmWOqdYQeQVNfa5L9bEAQM6Z2AOpuz0cAbX0XejizjBqfJQyy+\n+aE85OcDntaJR05dwGGfFnMnymqx8P92Ys1HRY0+XxqeIt2wXDu8B+KMGuw6VNaoc4XD6ca3P5R7\nbmjSTEiM0+HVOVfjV1OHyQGqQhAwaaxnuM22fWdwoKQSRr26WVmYpDg9np99JR694zLcPLYXrhmW\n7vfncj9v79qlerVQ3S2ikVopwOVyy6PqWW5BdGkM6JWA398/+pK8B14MUmxw6Mcq/OqVL/DrP23D\n/67/BvNf247Hln8ZtF65rNrqmbfQwa+Zeq0KAsK3uJO6W3SZcosfvYdppPqfHkkxqK61+TXLlu6C\nIsk4piQY8MSsUfhN7hURr2FgZgKe/dk4/OLOpqfq9PGOY5Y6I5ScroFKqUBmmDpHya3jMjF6YAoe\nveOyJmtwjfqWl1u0lO+BpktxgTDq1Xhi1ijkTex/0f/u5pJGbCbG6SEIAm67MhNPPzwWV3sDtHPn\nrbA7XDh88gJ6pRj9emYPzvIEzN8cCR3AejqENHyNVPojdV0J5sezNTDFaNDNpMWgzARoNUq5RjwY\ntyjK5T7f/tBQv7zNO1L5/+063ijDLNVaSwcrFAoBVw1JQ53NiW9+8K+B3nnwLGrqHLhmWLo8AlkI\n8nRiUGYCEk1afHngLM6b7RjSu1uznmIAnp/z0QNTMP3afkHLKJLidKi8YIVbFJtdbhENlEoFHC53\nQyb5Io3IJaLORcokf/HdaYjwZI8P/VgNs9WBqhpbo4PUbreIc9V1SOtmCHr97kgUggC9VhV2WIpD\n7m7RRfokl3gDAymgCOxdDABn5CA58kcFzf1h8HSnaPouS6tRom8PE0rO1KC61oZT5Wb0SjVGlNmJ\nM2rx6B2XRZRl65FshIDwJ/Evtl4+/1ZLW7g0+W+kxjaZrW8LUiZZGiyhUSvRPSkGBp0aRr0aZdVW\nlJypgdPlbtSlYUT/ZCgVAnYXBR98Y3d4evr6Bcnev6Po+Hm4RRFvbz6Cr3y+vsZiR1WNDVlpsRAE\nAWqVAv26m3Cmsi5ku5/qGpucWfz2hwqIoginy41d35fJf+d3R/2D7MBMMgBcNdRzY7B9f8MBPrco\n4qPdJ6BUCJg4KnzNuEIQcNVl6fKkvOaUWkQqKV4Pp0vEBbO92Qf3ooFKqYDLJcLmZE0yUVcmZZJ/\nOHUBSoWAF39+Ff7y6xz8/A5Pki/wUHlFTT2cLhFp3TpWCVkoMfrwBxOlcouWdh7pVFfOCwGBAdBQ\nj+gfJFugVSs7zOOPoX0SIYrAf3Ydh8stoncT9cgt0TPFiD//+hqMGhD6cN/FJgXkMTpVi2fLdxZS\nkJwYpPY0NcEzhVAqfwgspTHq1RiUlYDjZ2sbTfQDgGqzdGiv4ec13uipTT5y6jy+OVKOzV+dwvvb\nSuQ///Gs/xMVAOjt7aQhPW0JdKaq4TVSWVOPU+UWHCipQm2dA4O8Qfk2b29gSVVNPTRqhXyhBTxP\nb3qnm3CgpBLnvWs/UFyJM5V1GDs4NaLX3XifEokhlyBIlnobV1ywoqbODkFoqNvvCqSDew4Ha5KJ\nujKp1awIT/mnTqOCQaeSD5UHBsmdpR5ZYtCpw/aBdrjcUCqEZj+tlEQUJFdWVmLChAkoKSlBVVUV\nfv7znyM/Px95eXk4efIkAGDjxo2YOnUqcnNzsWXLFgCAzWbDnDlzMHPmTMyePRvV1aEfHUfiuLce\n2TcwSO/mCZKlg1Nut4izVVakJXacRwVSQf/Wbz0BSFb6pTkFa9Cp23TPKfF6xOhUQaflRRup0kFa\nvwAAIABJREFUH26wTH1KgmcK4c5DnoxsdpAa6tEDPX2dvwqSTa6uaehs4Wtgr3jY7C6s+e8RAJ4b\nQalLyo/ya6Hhhku6+QrVSUO6+En1y3sPn8N27/S6aRP6ol9GHPYXV/l1rqisqUeiSdfo5+rqYekQ\nRWD1x4dx3mzD25t/AADcGKaLiK+UeD1yLu+OcUNS/UpTLpYk+fBePWotnpHULb1IdkYNLeA8mWTW\nJBN1TTE+T7wH+yQkTDEaJJp0KA44VC7FUp3lfT1Gp4Ld4Q456MrpdLfq+tfkVzqdTixevBg6necN\n/MUXX8Ttt9+O1atXY+7cuSguLkZFRQVWr16NDRs2YOXKlSgoKIDD4cC6devQv39/rF27FlOmTMGy\nZctavFCgIUPm27c0xftIQDo45XlU4G5WqcWl1ivViLgYjVwfGK7vameiUAh4bMZw/PS2we29lEsu\nMy0Wj88aidtz+jb6M6nTRVlVHVK7GYJ2UZBKLrZ8U4pN20r87t59O1v4kkouLpjt8oAMaVSy9FrI\nDJJJDjW45Iz34nfD6J5QCAI2bf8Re4+UI62bAVlpsZg4uhfcoiiXhVhtTljqnUEbvV8zLB2DMhPw\nzQ8VePyNnThXbcWtV2Y22TLN1/03D8TPJg+J+PObI8mbSS6/YEVNmJHU0UqlkFrASTXJDJKJuiLf\noWWBpW29u5tgtjrkdplAQ5vazpRJBkIf3nO43C1u/wZEECQvXboUM2bMQEqKJxP29ddf4+zZs3jg\ngQfw4YcfYuzYsdi3bx9GjhwJlUoFo9GIrKwsFBUVYe/evcjJyQEA5OTkYMeOHS1eKBD8EXOsXg29\nVil3DjjjLbtI70DfYEEQ5GyyTqNs1hSbjq5XamynueNsrb7d44JOEkpJaCjBCJZFBjx381f0S0LF\nhXr8c1sJlq79Wr4YVdV6LlCBZQoDfPp233GNp8uG1Jf6eFkt4oyaRiUaCbFalJzxZAaKjlcHPdDa\np7sJt1yZieyMOIy/LA0P3DIQgiBgzBBPCYTUlq3KG7wnBhnLrFIq8Is7hyIjOQZWmws/uaI77srp\nE3Tv7UEKks9W1sFqc3apQ3tAQ7sjq3dkOsstiLomKZMco1PJk4YlfYKUXEjvS5GOpG5vUimgJUQb\nOKfrEmaSCwsLkZiYiPHjx0MURYiiiNLSUsTHx+PNN99EWloaXn/9dZjNZsTGNvzPNxgMMJvNsFgs\nMBq9dasxMTCbQ7ezaorV5sT3J6qRFKdDnM/jWUEQkJJgwLlqz0n2M83obNGWpAERWWmxXeqxb1eQ\n4nMxCRUkA8DPbh+MJ+8bhRnXZ8PudGPlh4fgcrt9Bon4B8lxMRoMyUrAwF7xmOTt11x0vBoXzDZU\n19qC1rb3STfhgsWOD7/8ES+s+wbPr/1a7iF5ptKCRJMWWrUSd+X0waJ7R+Kh2wbLNdTJCXr0SIrx\nTHh0uORDe6F6YBt0Kvw2bwR+cedlyL9xQIcpbwI8QbJCEOQSmK50aA9oaJxvtXmDZGaSibqkOKMG\nguA5+yF1HZL09pZ+BgbJ3UzaTnPOSLoJCDV62+kSoVK2/L0pbL+wwsJCCIKA7du34/Dhw1iwYAGU\nSiWuvfZaAMB1112Hl19+GUOHDvULgC0WC0wmE4xGIywWi/wx30C6KcnJ/p/7nx0/wmZ3Ydp12Y3+\nLDPNhONnayGoVaj21mwOzk5u9HntaUKsDl/sP4ObxmbK6+pI67tYonFPgQL3qI9pCG7HDeuB5DB9\nmbunx2PMsB44U23Flq9P4YsDZbDYPHWj2b2TGpVqPP+rHIiiCEEQMKxfEnYdPIvPvvPUEQ/um9Ro\nLZdlJ2PvkXK894XnkN+pcgv+VLgfTzwwBufNdgzvH/51MeaydLy35SjKauywe8vUemfEh/yaZAC9\ne138g3cXw//kjcDHO3/EoZIqXD4gJapfdxJpbwbpkKLCExwnJRmjYt/RsIemRPMeo3lvko62x+Tk\nWDzz6Hj0So31SzACgNGkh0L4Bqcq6pCcHIt6mxPVtTZcnt34vUX6uzqaFG9CVKVVBV2f0yXCaFC3\neO1hg+Q1a9bIv541axaeeuopvPLKK9iyZQumTJmCPXv2IDs7G0OHDsXLL78Mu90Om82G4uJiZGdn\nY/jw4di6dSuGDh2KrVu3YtSoUREvrLy84YS+KIr44PNjUAgCRvRN9PszoGFIwPdHy3GopBIalQIa\niI0+r73Nm345AM/ekpNjO9z6Wisa9xQo1B5NBs+hSZXojuj/wdSc3vjq+zIUfnYUcUYN1CoF6i31\nsNUFH/cMAH3SY7Hr4Fls+qIYWo0SgzJMjf6tFJ9R3ndf2w+nKy3Ytu8MHl+2HQCQGKsNub7k5Fj0\nTfME+F98c1IuLVF3wNdSJIb0jMOQnpfD7RahUAhR+7qT+O7N5T3/UOkdL2u12Dr9vqP5eyeJ5j1G\n894kHXWPaSYt7FY7yq2NxzenJ8Xgh5PVKDtXI08EDvY+0VH3Jro8SaYzZbUoT25cQWB3uiAAYdce\nLoBu9uSJBQsW4IknnsD69esRGxuLgoICxMbGyt0uRFHEvHnzoNFoMGPGDCxYsAB5eXnQaDQoKCho\n7j8HwHNa/+Q5M0b2Tw7aXirVWxN67HQNSsstGJSZ0KpCbaLmevSOy6BUKiIuOYjRqXHNsHT8Z9cJ\nmK0OpCTom/za4f2S8P4XJeiXEYdZNw0IWgaRlRYLjVqBtG4G3DA6A4Cn17FUyxzJFEqtWolvf6iQ\n+1MHq0nuTAIfMXYF0vWvTiq3UPN6SESN9UwxorTcgvLzVpRWeILkHkkdq1w1HKncwhyiDZzT6W7x\ntD2gGUHyqlWr5F//7W9/a/Tn06dPx/Tp0/0+ptPp8Oqrr7Z4cZJt3jZVE0b0CPrn0sGx7fs9nzeg\nZ/iRz0QXm+8hu0hNGN4DH+06ARFAQgRt0JLi9fjTr68JW9Ou16qw+P7RMMVooPQ+an9kyhAs+ftX\nqKypR1oTtfpqlQKDMhPw7dEKVFyox8Be8ZdsUAxdOlINnlSTrObEPSIKQgqIS8stOF3hefLUvVMF\nyZ4wNlhNslsU4XKLrUqatt0M41Y4VnoBWrUSg0IEIlJ3AakN3IBeDJKp40uO12NY30R8d6wSCabI\negVHcugz8NBqrEGDefdcjr2HyyO6gbxpTE84XG5cMywdowam8KBpJyRnkut5cI+IQpNmAJwqN+O0\ntztYZwqSG1rANc4ku7y9k1WtuP51+CDZ4XThTGUdstJjQz429bSBU8Fqc0KlFKKmDzFFv4mje+K7\nY5WXvBtLemIMbrsqsn9jQK+EFmXGqeNgdwsiikSP5IZMcmmFGbEGdadqmRkukyzNpmiTcov2crqi\nDi63iF4poQurBUFAaoIeP56tRZ90E3uCUqcxJKsbFt8/Oqp6Z1P7k8otGmqSeU0kosYSTTroNEqU\nnKlB5YX6TvckXs4kB+mT7HB5WjS1JpPc4dMLJ855TiT2TA3dVgtoqEvu38m+wUSZabFBh5QQtZQy\noNyCY6mJKBhBENAjOQYVF+ohwtPtojPRa5VQCAIstsaZZKecSW55yWCHv3JKLUnCZZIBzwlNwJOZ\nIyLqyqQ3BZdbhEIQ2O2HiELK8Ont35k6WwCeIN+gUwUtt3BKNcnRXG5x4pwZgtBQNxPKxJEZ6J8R\nj35hJp4REXUFvm8KbP9GROH4BsbdO9i04kgYdKqgB/ccF+HgXoe+eoqiiJPnapHWzdDk42iNWskA\nmYgIDeUWAA/tEVF4vpnk7k0kJDuimBCZ5ItxcK9DXz0rLtTDanPJpRRERNQ0lU8NHnskE1E40pN6\no14NUyfqbCEx6NRwON2wO1x+H5fKLVpzJqNDl1ucPOetR07tePPCiYg6KpZbEFGkYg0aDOndDSnx\n+vZeSotIbeAs9U6/Tj7Swb2orUkuLfcEyb6PAoiIKDzfTLKGmWQiasL8e65o7yW0mDSauq7egYTY\nhsFccgu4aO1uYfHWmJhi1O28EiKizsM3c6JmJpmIopjBJ5PsSy63iNaa5Hq7Z8N6TYdOeBMRdSgq\nHtwjoi4iJsRoaungXtR2t7DaPEXYOg0fFxIRRYrlFkTUVYQaTd0FMslSkMxMMhFRpJQ8uEdEXYQ8\nmjogSI76Psn1dicEgRd5IqLmUCl8W8Dx+klE0csgZ5L9yy2c0d4n2WpzQadRQRBafjKRiKir8c2c\nsNyCiKKZNGzO7g2KJU65u0WUBsn1difrkYmImkml8OluwUwyEUUxqdogcJiIw+n5vUoVpS3g6u0u\nBslERM3kd3BPzWsoEUUv6Rpnd/hnkqU+yVFbbuEJknloj4ioOfzLLTr0ZZ6IqFW03muc3Rl8LHVU\nHtxzutxwutzQa5kFISJqDt9yCwbJRBTN1KrgmeQ2O7hXWVmJCRMmoKSkRP7YBx98gNzcXPn3Gzdu\nxNSpU5Gbm4stW7YAAGw2G+bMmYOZM2di9uzZqK6ujnhhbP9GRNQyLLcgoq5CrkkOlUm+lEGy0+nE\n4sWLodPp5I8dOnQI7777rvz7iooKrF69Ghs2bMDKlStRUFAAh8OBdevWoX///li7di2mTJmCZcuW\nRbywepun3x1rkomImsf38SIP7hFRNFMpFVAqhMY1yVIm+VKWWyxduhQzZsxASkoKAOD8+fN45ZVX\n8Pjjj8ufs2/fPowcORIqlQpGoxFZWVkoKirC3r17kZOTAwDIycnBjh07Il6Y1c5pe0RELeFXbsFM\nMhFFOY1a0bi7xaXOJBcWFiIxMRHjx4+HKIpwuVx4/PHHsXDhQuj1evnzzGYzYmNj5d8bDAaYzWZY\nLBYYjUYAQExMDMxmc8QLq7d7Msl6LcstiIiaQ6nkMBEi6jo0KiVsIfokt+YaGDYCLSwshCAI2L59\nO4qKinD77bcjIyMDf/jDH2Cz2XDs2DE899xzGDt2rF8AbLFYYDKZYDQaYbFY5I/5BtJN0eo1AIDE\nBAOSkyP/us4kGvcVjXsKFM17jOa9SaJ5j9LeRFGUP5aSZIyaPUfLPsKJ5j1G894k0bzHjrw3vU4F\np9Ptt0aFN4OclmpqccI17FetWbNG/nV+fj6efvppZGVlAQBKS0sxf/58LFq0CBUVFXjllVdgt9th\ns9lQXFyM7OxsDB8+HFu3bsXQoUOxdetWjBo1KuKFlZV7gm6Xw4Xy8toWbK1jS06Ojbp9ReOeAkXz\nHqN5b5Jo3mPg3lRKBZwuN+ostqjYczR/7yTRvMdo3pskmvfY0femVAiotTn91mipswMAzldbYA5T\nchEu+I84tBYEwS874SspKQn5+fnIy8uDKIqYN28eNBoNZsyYgQULFiAvLw8ajQYFBQWR/nOw8uAe\nEVGLqZQCnC62gCOi6KdRKYOMpXZDgCeAbqmIg+RVq1b5/b5Hjx5Yv369/Pvp06dj+vTpfp+j0+nw\n6quvtmhhbAFHRNRynsMqLtYkE1HU06oVcDjdcIsiFIInKHa6RKhUCghCFI6llg7u6ThMhIio2aRe\nyVp2tyCiKCd18XH4tIFzudx+PeNbouMGyTa2gCMiaimp7REzyUQU7dRBRlM7XG4oFa27/nXYq6ec\nSWa5BRFRsym9QbJGxUQDEUU3TZDR1C6XGMWZZG9Nsp6ZZCKiZlN73xzU6g57mSciuii0QUZTO93u\nVg0SATpwkNzQ3YKZZCKi5lKrlNCoFfIhFiKiaCXVJPtmkp0usdVBcoeNQOs5lpqIqMXuyumD82Zb\ney+DiOiS03gzyTaf0dROpxsqQ+uSBB06SNaoFVC0or8dEVFXNaR3t/ZeAhFRm5BrkgPKLZTRWm5R\nb3dCz1ILIiIiIgojWLmFyyVCHa1BstXuYqkFEREREYUllVvYveUWblGEyx3V3S2cPLRHRERERGFp\n5XILTybZ5fL8NyrLLVxuEXaHG3pO2yMiIiKiMAIzyU6XCABQtfJcW4cMktn+jYiIiIgioQ7IJDu9\nmWRVKyeOdswguV4KkplJJiIiIqLQtKEyydFYbmG1OQAwSCYiIiKi8AK7W8iZ5Kgut9Cy3IKIiIiI\nQtN4yypsTimTHMUH9+pYbkFEREREEWjIJHuCZJe33CIq+yTz4B4RERERRaJRuYVbyiRHc7kFM8lE\nREREFIZUbiEf3HNG8cE9S73n4J6BNclEREREFIbcJzmwBVxUZpKlmmQOEyEiIiKiMJQKBVRKoSGT\n7JaC5DbIJFdWVmLChAkoKSnB999/j5kzZ2LWrFl4+OGHUVVVBQDYuHEjpk6ditzcXGzZsgUAYLPZ\nMGfOHMycOROzZ89GdXV1RIuSDu7pWZNMRERERE3QqJQ+meQ2KrdwOp1YvHgxdDodRFHEs88+i9//\n/vdYtWoVbrjhBrzxxhuoqKjA6tWrsWHDBqxcuRIFBQVwOBxYt24d+vfvj7Vr12LKlClYtmxZRIuq\n89Yk61luQURERERNUKsVPjXJbXRwb+nSpZgxYwZSUlIgCAJefvllDBgwwLsIJzQaDfbt24eRI0dC\npVLBaDQiKysLRUVF2Lt3L3JycgAAOTk52LFjR0SLqvPWJDNIJiIiIqKmaH0zyW1RblFYWIjExESM\nHz8eouhJXSclJQEAvv76a7z99tu4//77YTabERsbK3+dwWCA2WyGxWKB0WgEAMTExMBsNke0KPZJ\nJiIiIqJIaXwyyS653KJ1meSwqdrCwkIIgoDt27ejqKgICxYswPLly7Fr1y6sWLECr7/+OhISEmA0\nGv0CYIvFApPJBKPRCIvFIn/MN5AOx2pzQhCAjO7xULRypGBHlpwc2f+PziQa9xQomvcYzXuTRPMe\no3lvQPTvD4juPUbz3iTRvMeOvrcYvQZl1VYkJ8dCb6gEAHSLN7Rq3WGD5DVr1si/zs/Px5IlS7Bt\n2zZs3LgRq1evhslkAgAMGzYMr7zyCux2O2w2G4qLi5GdnY3hw4dj69atGDp0KLZu3YpRo0ZFtKi6\negd0GiUqKyPLPHdGycmxKC+vbe9lXFTRuKdA0bzHaN6bJJr3GM17A6J/f0B07zGa9yaJ5j12hr0J\nEOFwulFWVoPq81YAQF2dvcl1hwuiIy76FQQBLpcLzz77LLp3745f/OIXEAQBY8aMwS9/+Uvk5+cj\nLy8Poihi3rx50Gg0mDFjBhYsWIC8vDxoNBoUFBRE9G9Z6p2ctkdEREREEZGn7jldDX2SW1mNEHEk\numrVKgDArl27gv759OnTMX36dL+P6XQ6vPrqq81elLXegViDptlfR0RERERdj+9oajlIVkXhxL26\neif0HCRCRERERBHQ+oymlg/utTKT3CGDZJdb5CARIiIiIopIQ7mFGw6X1Cc5CjPJAKBjj2QiIiIi\nioBG7c0kO30yydEaJOvZI5mIiIiIIqBWBalJvtQT99oLp+0RERERUSS06oaaZKc7yjPJnLZHRERE\nRJHQeDPJNocLTiczyURERERE0Gp8yi3cUpAcpZlkBslEREREFAmtt7tFvcMFZ9Qf3GOQTEREREQR\nkDLJNrsLrqg/uMeaZCIiIiKKgE7KJNud7JNMRERERAT4ZJJ9J+4xk0xEREREXZnOp9zC6XJDEACl\nIkozyaxJJiIiIqJIBB7ca+2hPaADB8k6DYNkIiIiImpaYCa5taUWQEcOkrUstyAiIiKipmnkg3ue\nILm1pRZABw2S9VoVFELr7wCIiIiIKPqplAqolAr54J5aFaVBskHHUgsiIiIiipxOo/SUW7jdUCqi\ntNyCQTIRERERNYdWrfSUWzjd0Xtwz6BVt/cSiIiIiKgT0WqUsMndLdook1xZWYkJEyagpKQEJ06c\nQF5eHu6991489dRT8uds3LgRU6dORW5uLrZs2QIAsNlsmDNnDmbOnInZs2ejuro6okXpmUkmIiIi\nomaQM8nuNsokO51OLF68GDqdDgDw3HPPYd68eVizZg3cbjc2b96MiooKrF69Ghs2bMDKlStRUFAA\nh8OBdevWoX///li7di2mTJmCZcuWRbSoGB0zyUREREQUOZ1GCafLDYejjYLkpUuXYsaMGUhJSYEo\nijh06BBGjRoFAMjJycGXX36Jffv2YeTIkVCpVDAajcjKykJRURH27t2LnJwc+XN37NgR0aJYk0xE\nREREzSENFBHR+pHUQBNBcmFhIRITEzF+/HiIomcOttvtlv88JiYGZrMZFosFsbGx8scNBoP8caPR\n6Pe5kejdPa7ZGyEiIiKirksaKAIAyouQSQ6bsi0sLIQgCNi+fTsOHz6MBQsW+NUVWywWmEwmGI1G\nvwDY9+MWi0X+mG8gHc7ka/qgvLy2JfshIiIioi5I6xMkqy91kLxmzRr517NmzcJTTz2FF154AXv2\n7MHo0aPx+eefY9y4cRg6dChefvll2O122Gw2FBcXIzs7G8OHD8fWrVsxdOhQbN26VS7TiERycmQB\ndWcWjXuMxj0FiuY9RvPeJNG8x2jeGxD9+wOie4/RvDdJNO+xM+wtIU4v/9pgULd6zc0u/l2wYAGe\nfPJJOBwO9O3bF5MmTYIgCMjPz0deXh5EUcS8efOg0WgwY8YMLFiwAHl5edBoNCgoKIj434n2THJy\ncmzU7TEa9xQomvcYzXuTRPMeo3lvQPTvD4juPUbz3iTRvMfOsje30yX/2uV0R7TmcIF0xEHyqlWr\n5F+vXr260Z9Pnz4d06dP9/uYTqfDq6++Guk/QURERETUIr7lFqponbhHRERERNQcOrVPkKyK0ol7\nRERERETN4Z9JZpBMRERERAStuqGKWNlWY6mJiIiIiDoy3z7JbTJxj4iIiIioo/Mrt2AmmYiIiIio\nYSw1wEwyERERERGAwEwyg2QiIiIiIr8WcDy4R0REREQE/0yymplkIiIiIiJAo1JAyh8zk0xERERE\nBEAQBDmbzJpkIiIiIiIvBslERERERAGkw3vsk0xERERE5MVMMhERERFRADmTrGAmmYiIiIgIAKDV\nqAAASmaSiYiIiIg8pHILtYpBMhERERERgIZyCyXLLYiIiIiIPHqlGmHQqtDNpGv136W6COshIiIi\nImp3E0f1xLUjekCpaH0euMkg2e1244knnkBJSQkUCgWeeuopOJ1OLF68GCqVCllZWXjmmWcAABs3\nbsSGDRugVqvxyCOPYMKECbDZbHjsscdQWVkJo9GI559/HgkJCa1eOBERERFRoIsRIAMRlFt8+umn\nEAQB69atw9y5c/HSSy/htddewy9/+UusXbsWNpsNW7ZsQUVFBVavXo0NGzZg5cqVKCgogMPhwLp1\n69C/f3+sXbsWU6ZMwbJlyy7KwomIiIiILpUmg+SJEyfi6aefBgCUlpYiLi4OgwYNQnV1NURRhMVi\ngUqlwr59+zBy5EioVCoYjUZkZWWhqKgIe/fuRU5ODgAgJycHO3bsuLQ7IiIiIiJqpYjy0QqFAgsX\nLsQzzzyDyZMnIzMzE8888wxuvfVWVFVVYcyYMTCbzYiNjZW/xmAwwGw2w2KxwGg0AgBiYmJgNpsv\nzU6IiIiIiC6SiA/uPf/886isrMS0adNgs9nw9ttvo2/fvli7di2ef/55XHPNNX4BsMVigclkgtFo\nhMVikT/mG0iHk5wc2ed1ZtG4x2jcU6Bo3mM0700SzXuM5r0B0b8/ILr3GM17k0TzHqN5b6E0mUl+\n//338frrrwMAtFotFAoF4uPjERMTAwBITU1FTU0Nhg4dir1798Jut6O2thbFxcXIzs7G8OHDsXXr\nVgDA1q1bMWrUqEu4HSIiIiKi1hNEURTDfYLVasWiRYtQUVEBp9OJn/3sZ4iPj8eLL74IlUoFjUaD\np59+Gt27d8c//vEPbNiwAaIo4tFHH8XEiRNRX1+PBQsWoLy8HBqNBgUFBUhMTGyr/RERERERNVuT\nQTIRERERUVfDiXtERERERAEYJBMRERERBWCQTEREREQUgEEyEREREVGAdg+S8/PzUVJS0t7LuOhK\nS0sxcuRIzJo1C/n5+Zg1a1bIkdyd5f/B7t27MXDgQPz73//2+/jkyZOxaNGidlrVpfPGG2/g6quv\nht1ub++ltFpX+94Bned11VLh9nfdddd12p/baHrdBfP666/jgQceQH5+Pu677z4cPHiwvZd0UZ06\ndQpz5szBrFmzkJeXhyVLlsizEgKdOXMGn332WRuvsOV2796NUaNGoaysTP5YQUEB/vnPf7bjqi6O\n3bt346qrrpJjlhkzZuA///lPey+r3UU8TISaLzs7G6tWrWrvZVxUffr0wb///W/ccsstAIAjR46g\nvr6+nVd1aXzwwQe47bbb8K9//Qt33nlney+n1brS966rEwShvZfQYtH2uvN17NgxfPrpp1i/fj0A\noKioCAsXLoyKIAsAbDYbHn30UTz77LMYOnQoAOCf//wn5s+fj//7v/9r9Pk7d+5EcXExrr322rZe\naotpNBosWrQIf/vb39p7KRfdlVdeiYKCAgBAXV0d7r33XvTu3RsDBw5s55W1n3bPJANAVVUVHnnk\nETz00EOYPHkyPvnkEwDA7bffjj/+8Y9yJrazjbQO1l3vpZdewsyZM5Gbm4uPP/5Y/virr76K++67\nDz/72c9QXV3dlstsloEDB+L06dPy92LTpk24/fbbAQBr167Ffffdh3vuuQePPPIInE4n3nvvPdx7\n772YOXMmdu7c2Z5Lb5bdu3cjMzMTubm5ePvttwF4MneLFy9Gfn4+8vPzUVlZid27d+Puu+/Gvffe\ni02bNrXzqsNrzvfO4XBg/vz58iCgY8eOYfbs2e229pb685//jA0bNgAAiouLkZ+fD6DzX1skofbX\nWTt7hnrdSRnz9evX4y9/+QsA4LXXXsNdd92Fhx56CDNnzsSePXvabd2RMhqNOHv2LN555x2UlZVh\n4MCB+Mc//oEjR45g1qxZmDVrFubMmQOz2Yzdu3fjwQcfxEMPPYQ77rgDa9eube/lN2nLli0YO3as\nHCADwB133IHz58/j+PHjyM/PR25uLh544AFUVlbi9ddfx7/+9a9OlU0eN24c4uLiGn0ChvTWAAAJ\n1klEQVQ/3nzzTUybNg25ublyoDl16lScPn0aAPDxxx/j2WefbfP1tpTBYMCMGTPw0Ucf4aWXXkJe\nXp5f3PLdd98hNzcX99xzD+bMmRO1T346RJBcVFSEhx56CH/961+xZMkS+eJoNpsxefJkrF69Gikp\nKfj888/beaXNc/ToUb9yiw8++ACnTp3C2rVrsWrVKixfvhy1tbUAgJtuuglvvfUWJkyYgBUrVrTz\nysO78cYb8d///hcAsG/fPgwfPhxutxvnz5/HW2+9hQ0bNsDhcGD//v0AIF9Qxo0b157LbpZ//OMf\nmDZtGrKysqBWq7Fv3z4AwMiRI7F69WrccsstWL58OQDAbrdjzZo1csDZkUX6vTtw4ADuuecevPfe\newCAd999F9OnT2/PpbdIYEZV+n1nv7ZIQu2vswr2ugu2p6KiImzbtg2FhYVYtmwZKioq2mG1zZea\nmorly5fj66+/Rm5uLm655RZ89tlnePLJJ7F48WKsWrUKOTk5eOONNwAA586dw4oVK7Bhwwa89dZb\nqKqqaucdhHfy5En07Nmz0cd79OiBqVOn4pFHHsH69esxa9YsHD58GLNnz8Ztt93WqTLJgiDgD3/4\nA9566y2cOHECgOd68tFHH2Hjxo1Yv349jh8/ji1btmD69OnyNbSwsBB33313ey692bp164aPPvoI\npaWlePvtt/3ilsWLF+O5557Dhg0b8JOf/ATHjh1r7+VeEu1SblFXVwetVgulUgnAE3i88cYbeOed\ndwAADodD/txBgwYBANLT0zvdnUpgucXKlStx8OBBzJo1C6IowuVyobS0FADkcd0jRozo0G/YgiDg\ntttuw+LFi5GRkYHRo0dDFEUoFAqo1WrMmzcPer0e586dg9PpBAD07t27nVfdPDU1Nfj8889RVVWF\n1atXw2w2Y82aNRAEAWPHjgUADB8+XH7i0Vn219zv3ZgxY/D000+jqqoK27dvx/z589t7C00KvLb4\nCsyudsZrS3P219mEet35kvZYXFyMYcOGAQC0Wi2GDBnS5uttiRMnTiAmJkbOKB48eBAPP/ww7HY7\nnnrqKQCA0+lEZmYmAM91RqVSQaVSITs7GydPnkS3bt3abf1NSU1NlRMKvo4fPw6bzYbLL78cAOSg\nWAogO5u4uDgsWrQICxYswMiRI+W9KRSevOOIESNw9OhR5ObmIi8vD9OnT4fFYkG/fv3aeeXNc/r0\naUyePBmbNm1qFLdUVFTI731Tp05t55VeOu2SSV64cCH27t0Lt9uNqqoqPP/887jjjjuwdOlSjB07\nttNf7CWB++jTpw/Gjh2LVatWYdWqVZg0aZJ81y1dWL766itkZ2e3+VqbIyMjA1arFatXr5azp2az\nGZ988gleeuklPPnkk3C5XPL+pQtHZ/H+++9j2rRp+Otf/4qVK1di48aN2L59O6qrq+VDNnv37pW/\nT51pf8393k2ZMgXPPPMMrr766qCBWUcTeG0ZMGAAzp07BwBRcUAqmvcX6nWnVCrlPR46dAgA0K9f\nP/lJld1ulz/e0R0+fBhLliyRE0GZmZkwmUzIzMzECy+8gFWrVuE3v/mNHEQeOnQIoijCarXi6NGj\ncvDcUV1//fXYsWOH/L0BPE8HunXrhgkTJsgf/+CDD7B27VoIggCXy9Vey22Va6+9Fr1790ZhYSG0\nWi327dsHt9sNURTx1VdfISsrC0ajEUOGDMFzzz2Hu+66q72X3CTfmMVsNmPjxo0wmUxB45aUlBQ5\nk/7GG29g8+bN7bXsS6pdMskPPvggnn76aQiCgEmTJqFv375YunQpXn/9daSkpOD8+fMA/B8ddsbH\niIFrvu6667B7927MnDkTVqsVEydORExMDARBwObNm/H3v/8dsbGxWLp0aTutOHK33HILNm3ahMzM\nTJw4cQIqlQp6vR4zZswAAKSkpMhvbJ3Nu+++ixdeeEH+vU6nw4033oh33nkH7733Ht58800YDAa8\n8MILOHz4cDuutGWa872788478corr+DDDz9szyVHzPfacvPNN+PWW2/F3LlzsWfPHr9sY2e9trRk\nf51FsNfdTTfdhLS0NCxZsgTp6elITU0FAPTv3x85OTm4++67kZCQALVaDZWq459Dv+GGG1BcXIxp\n06YhJiYGbrcbv/3tb5Geno7HHnsMLpcLCoUCzzzzDMrKyuB0OvHwww/j/Pnz+PnPf474+Pj23kJY\nBoMBy5cvx7PPPosLFy7A5XJhwIABeOmll1BVVYXf//73WL58OfR6PV588UWUlpZixYoVGDJkiHyg\nuDP53e9+h507d8JoNGLSpEnIzc2FKIoYOXIkJk6cCAC4++678dOf/hTPPfdcO6+2abt27cKsWbOg\nUCjgcrkwd+5cTJw4Ec8//3yjuOWpp57CokWLoFAokJKSgvvvv7+9l39JCGK0pG2JLrH8/HwsWbKk\n05RXXAxlZWVYuHAh3nzzzfZeCpGsqqoKH330EfLy8mC32zF58mS89dZbSEtLa++lXTS7d+/Ghg0b\n5ENgRNT2Ov6tN1EH0Rmzc63x3//+F3/+85/lWkmijiIhIQH79+/HtGnToFAoMH369KgKkImoY2Am\nmYiIiIgoQJtlkp1OJ373u9+htLQUDocDjzzyCPr164eFCxdCoVAgOzsbixcvlj+/qqoKM2bMwAcf\nfACNRgOz2Yzf/OY3sFgscDgcWLhwIa644oq2Wj4RERERdSFtFiRv2rQJCQkJeOGFF1BTU4MpU6Zg\n4MCBmDdvHkaNGoXFixdj8+bNmDhxIrZt24aCggJUVlbKX//mm2/KIxNLSkowf/58FBYWttXyiYiI\niKgLabPeVTfffDPmzp0LAHC5XFAqlTh06JDcHzgnJwc7duwAACiVSvz9739HXFyc/PUPPPAAcnNz\nAXiy0lqttq2WTkRERERdTJsFyXq9HgaDAWazGXPnzsX//M//+PXki4mJkafPXXnllYiLi/P7c6PR\nCI1Gg/Lycvz2t7/tFIMNiIiIiKhzatMpCGfOnMF9992HO++8E7feeqvfEAaLxQKTyeT3+YHdBA4f\nPowHH3wQ8+fPlzPQREREREQXW5sFyRUVFXjooYfw2GOP4c477wTgGQu7Z88eAMDnn3+OkSNH+n2N\nbyb56NGj+PWvf43//d//xdVXX91WyyYiIiKiLqjNDu6tWLECNTU1WLZsGV577TUIgoDHH38cf/zj\nH+FwONC3b19MmjTJ72t8M8kvvfQS7HY7nnnmGYiiCJPJhNdee62tlk9EREREXQj7JBMRERERBWjT\nmmQiIiIios6AQTIRERERUQAGyUREREREARgkExEREREFYJBMRERERBSAQTIRERERUQAGyURERERE\nARgkExEREREF+P/ODMa/AE3zGwAAAABJRU5ErkJggg==\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Plot the results\n", + "fig, ax = plt.subplots(figsize=(12, 4))\n", + "births_by_date.plot(ax=ax);" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "In particular, the striking feature of this graph is the dip in birthrate on US holidays (e.g., Independence Day, Labor Day, Thanksgiving, Christmas, New Year's Day) although this likely reflects trends in scheduled/induced births rather than some deep psychosomatic effect on natural births.\n", + "For more discussion on this trend, see the analysis and links in [Andrew Gelman's blog post](http://andrewgelman.com/2012/06/14/cool-ass-signal-processing-using-gaussian-processes/) on the subject.\n", + "We'll return to this figure in [Example:-Effect-of-Holidays-on-US-Births](04.09-Text-and-Annotation.ipynb#Example:-Effect-of-Holidays-on-US-Births), where we will use Matplotlib's tools to annotate this plot.\n", + "\n", + "Looking at this short example, you can see that many of the Python and Pandas tools we've seen to this point can be combined and used to gain insight from a variety of datasets.\n", + "We will see some more sophisticated applications of these data manipulations in future sections!" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "< [Aggregation and Grouping](03.08-Aggregation-and-Grouping.ipynb) | [Contents](Index.ipynb) | [Vectorized String Operations](03.10-Working-With-Strings.ipynb) >" + ] + } + ], + "metadata": { + "anaconda-cloud": {}, + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.4.3" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/pandas/03.10-Working-With-Strings.ipynb b/pandas/03.10-Working-With-Strings.ipynb new file mode 100644 index 0000000..49909b0 --- /dev/null +++ b/pandas/03.10-Working-With-Strings.ipynb @@ -0,0 +1,1404 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "\n", + "*This notebook contains an excerpt from the [Python Data Science Handbook](http://shop.oreilly.com/product/0636920034919.do) by Jake VanderPlas; the content is available [on GitHub](https://github.com/jakevdp/PythonDataScienceHandbook).*\n", + "\n", + "*The text is released under the [CC-BY-NC-ND license](https://creativecommons.org/licenses/by-nc-nd/3.0/us/legalcode), and code is released under the [MIT license](https://opensource.org/licenses/MIT). If you find this content useful, please consider supporting the work by [buying the book](http://shop.oreilly.com/product/0636920034919.do)!*\n", + "\n", + "*No changes were made to the contents of this notebook from the original.*" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "< [Pivot Tables](03.09-Pivot-Tables.ipynb) | [Contents](Index.ipynb) | [Working with Time Series](03.11-Working-with-Time-Series.ipynb) >" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Vectorized String Operations" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "One strength of Python is its relative ease in handling and manipulating string data.\n", + "Pandas builds on this and provides a comprehensive set of *vectorized string operations* that become an essential piece of the type of munging required when working with (read: cleaning up) real-world data.\n", + "In this section, we'll walk through some of the Pandas string operations, and then take a look at using them to partially clean up a very messy dataset of recipes collected from the Internet." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Introducing Pandas String Operations\n", + "\n", + "We saw in previous sections how tools like NumPy and Pandas generalize arithmetic operations so that we can easily and quickly perform the same operation on many array elements. For example:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([ 4, 6, 10, 14, 22, 26])" + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import numpy as np\n", + "x = np.array([2, 3, 5, 7, 11, 13])\n", + "x * 2" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This *vectorization* of operations simplifies the syntax of operating on arrays of data: we no longer have to worry about the size or shape of the array, but just about what operation we want done.\n", + "For arrays of strings, NumPy does not provide such simple access, and thus you're stuck using a more verbose loop syntax:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "['Peter', 'Paul', 'Mary', 'Guido']" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data = ['peter', 'Paul', 'MARY', 'gUIDO']\n", + "[s.capitalize() for s in data]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This is perhaps sufficient to work with some data, but it will break if there are any missing values.\n", + "For example:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "ename": "AttributeError", + "evalue": "'NoneType' object has no attribute 'capitalize'", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0mdata\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m'peter'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'Paul'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'MARY'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'gUIDO'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0;34m[\u001b[0m\u001b[0ms\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcapitalize\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0ms\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mdata\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m(.0)\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0mdata\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m'peter'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'Paul'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'MARY'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'gUIDO'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0;34m[\u001b[0m\u001b[0ms\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcapitalize\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0ms\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mdata\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;31mAttributeError\u001b[0m: 'NoneType' object has no attribute 'capitalize'" + ] + } + ], + "source": [ + "data = ['peter', 'Paul', None, 'MARY', 'gUIDO']\n", + "[s.capitalize() for s in data]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Pandas includes features to address both this need for vectorized string operations and for correctly handling missing data via the ``str`` attribute of Pandas Series and Index objects containing strings.\n", + "So, for example, suppose we create a Pandas Series with this data:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "0 peter\n", + "1 Paul\n", + "2 None\n", + "3 MARY\n", + "4 gUIDO\n", + "dtype: object" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import pandas as pd\n", + "names = pd.Series(data)\n", + "names" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can now call a single method that will capitalize all the entries, while skipping over any missing values:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "0 Peter\n", + "1 Paul\n", + "2 None\n", + "3 Mary\n", + "4 Guido\n", + "dtype: object" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "names.str.capitalize()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Using tab completion on this ``str`` attribute will list all the vectorized string methods available to Pandas." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Tables of Pandas String Methods\n", + "\n", + "If you have a good understanding of string manipulation in Python, most of Pandas string syntax is intuitive enough that it's probably sufficient to just list a table of available methods; we will start with that here, before diving deeper into a few of the subtleties.\n", + "The examples in this section use the following series of names:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "monte = pd.Series(['Graham Chapman', 'John Cleese', 'Terry Gilliam',\n", + " 'Eric Idle', 'Terry Jones', 'Michael Palin'])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Methods similar to Python string methods\n", + "Nearly all Python's built-in string methods are mirrored by a Pandas vectorized string method. Here is a list of Pandas ``str`` methods that mirror Python string methods:\n", + "\n", + "| | | | |\n", + "|-------------|------------------|------------------|------------------|\n", + "|``len()`` | ``lower()`` | ``translate()`` | ``islower()`` | \n", + "|``ljust()`` | ``upper()`` | ``startswith()`` | ``isupper()`` | \n", + "|``rjust()`` | ``find()`` | ``endswith()`` | ``isnumeric()`` | \n", + "|``center()`` | ``rfind()`` | ``isalnum()`` | ``isdecimal()`` | \n", + "|``zfill()`` | ``index()`` | ``isalpha()`` | ``split()`` | \n", + "|``strip()`` | ``rindex()`` | ``isdigit()`` | ``rsplit()`` | \n", + "|``rstrip()`` | ``capitalize()`` | ``isspace()`` | ``partition()`` | \n", + "|``lstrip()`` | ``swapcase()`` | ``istitle()`` | ``rpartition()`` |\n", + "\n", + "Notice that these have various return values. Some, like ``lower()``, return a series of strings:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "0 graham chapman\n", + "1 john cleese\n", + "2 terry gilliam\n", + "3 eric idle\n", + "4 terry jones\n", + "5 michael palin\n", + "dtype: object" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "monte.str.lower()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "But some others return numbers:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "0 14\n", + "1 11\n", + "2 13\n", + "3 9\n", + "4 11\n", + "5 13\n", + "dtype: int64" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "monte.str.len()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Or Boolean values:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "0 False\n", + "1 False\n", + "2 True\n", + "3 False\n", + "4 True\n", + "5 False\n", + "dtype: bool" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "monte.str.startswith('T')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Still others return lists or other compound values for each element:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "0 [Graham, Chapman]\n", + "1 [John, Cleese]\n", + "2 [Terry, Gilliam]\n", + "3 [Eric, Idle]\n", + "4 [Terry, Jones]\n", + "5 [Michael, Palin]\n", + "dtype: object" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "monte.str.split()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We'll see further manipulations of this kind of series-of-lists object as we continue our discussion." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Methods using regular expressions\n", + "\n", + "In addition, there are several methods that accept regular expressions to examine the content of each string element, and follow some of the API conventions of Python's built-in ``re`` module:\n", + "\n", + "| Method | Description |\n", + "|--------|-------------|\n", + "| ``match()`` | Call ``re.match()`` on each element, returning a boolean. |\n", + "| ``extract()`` | Call ``re.match()`` on each element, returning matched groups as strings.|\n", + "| ``findall()`` | Call ``re.findall()`` on each element |\n", + "| ``replace()`` | Replace occurrences of pattern with some other string|\n", + "| ``contains()`` | Call ``re.search()`` on each element, returning a boolean |\n", + "| ``count()`` | Count occurrences of pattern|\n", + "| ``split()`` | Equivalent to ``str.split()``, but accepts regexps |\n", + "| ``rsplit()`` | Equivalent to ``str.rsplit()``, but accepts regexps |" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "With these, you can do a wide range of interesting operations.\n", + "For example, we can extract the first name from each by asking for a contiguous group of characters at the beginning of each element:" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "0 Graham\n", + "1 John\n", + "2 Terry\n", + "3 Eric\n", + "4 Terry\n", + "5 Michael\n", + "dtype: object" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "monte.str.extract('([A-Za-z]+)', expand=False)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Or we can do something more complicated, like finding all names that start and end with a consonant, making use of the start-of-string (``^``) and end-of-string (``$``) regular expression characters:" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "0 [Graham Chapman]\n", + "1 []\n", + "2 [Terry Gilliam]\n", + "3 []\n", + "4 [Terry Jones]\n", + "5 [Michael Palin]\n", + "dtype: object" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "monte.str.findall(r'^[^AEIOU].*[^aeiou]$')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The ability to concisely apply regular expressions across ``Series`` or ``Dataframe`` entries opens up many possibilities for analysis and cleaning of data." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Miscellaneous methods\n", + "Finally, there are some miscellaneous methods that enable other convenient operations:\n", + "\n", + "| Method | Description |\n", + "|--------|-------------|\n", + "| ``get()`` | Index each element |\n", + "| ``slice()`` | Slice each element|\n", + "| ``slice_replace()`` | Replace slice in each element with passed value|\n", + "| ``cat()`` | Concatenate strings|\n", + "| ``repeat()`` | Repeat values |\n", + "| ``normalize()`` | Return Unicode form of string |\n", + "| ``pad()`` | Add whitespace to left, right, or both sides of strings|\n", + "| ``wrap()`` | Split long strings into lines with length less than a given width|\n", + "| ``join()`` | Join strings in each element of the Series with passed separator|\n", + "| ``get_dummies()`` | extract dummy variables as a dataframe |" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Vectorized item access and slicing\n", + "\n", + "The ``get()`` and ``slice()`` operations, in particular, enable vectorized element access from each array.\n", + "For example, we can get a slice of the first three characters of each array using ``str.slice(0, 3)``.\n", + "Note that this behavior is also available through Python's normal indexing syntax–for example, ``df.str.slice(0, 3)`` is equivalent to ``df.str[0:3]``:" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "0 Gra\n", + "1 Joh\n", + "2 Ter\n", + "3 Eri\n", + "4 Ter\n", + "5 Mic\n", + "dtype: object" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "monte.str[0:3]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Indexing via ``df.str.get(i)`` and ``df.str[i]`` is likewise similar.\n", + "\n", + "These ``get()`` and ``slice()`` methods also let you access elements of arrays returned by ``split()``.\n", + "For example, to extract the last name of each entry, we can combine ``split()`` and ``get()``:" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "0 Chapman\n", + "1 Cleese\n", + "2 Gilliam\n", + "3 Idle\n", + "4 Jones\n", + "5 Palin\n", + "dtype: object" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "monte.str.split().str.get(-1)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Indicator variables\n", + "\n", + "Another method that requires a bit of extra explanation is the ``get_dummies()`` method.\n", + "This is useful when your data has a column containing some sort of coded indicator.\n", + "For example, we might have a dataset that contains information in the form of codes, such as A=\"born in America,\" B=\"born in the United Kingdom,\" C=\"likes cheese,\" D=\"likes spam\":" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
infoname
0B|C|DGraham Chapman
1B|DJohn Cleese
2A|CTerry Gilliam
3B|DEric Idle
4B|CTerry Jones
5B|C|DMichael Palin
\n", + "
" + ], + "text/plain": [ + " info name\n", + "0 B|C|D Graham Chapman\n", + "1 B|D John Cleese\n", + "2 A|C Terry Gilliam\n", + "3 B|D Eric Idle\n", + "4 B|C Terry Jones\n", + "5 B|C|D Michael Palin" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "full_monte = pd.DataFrame({'name': monte,\n", + " 'info': ['B|C|D', 'B|D', 'A|C',\n", + " 'B|D', 'B|C', 'B|C|D']})\n", + "full_monte" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The ``get_dummies()`` routine lets you quickly split-out these indicator variables into a ``DataFrame``:" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ABCD
00111
10101
21010
30101
40110
50111
\n", + "
" + ], + "text/plain": [ + " A B C D\n", + "0 0 1 1 1\n", + "1 0 1 0 1\n", + "2 1 0 1 0\n", + "3 0 1 0 1\n", + "4 0 1 1 0\n", + "5 0 1 1 1" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "full_monte['info'].str.get_dummies('|')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "With these operations as building blocks, you can construct an endless range of string processing procedures when cleaning your data.\n", + "\n", + "We won't dive further into these methods here, but I encourage you to read through [\"Working with Text Data\"](http://pandas.pydata.org/pandas-docs/stable/text.html) in the Pandas online documentation, or to refer to the resources listed in [Further Resources](03.13-Further-Resources.ipynb)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Example: Recipe Database\n", + "\n", + "These vectorized string operations become most useful in the process of cleaning up messy, real-world data.\n", + "Here I'll walk through an example of that, using an open recipe database compiled from various sources on the Web.\n", + "Our goal will be to parse the recipe data into ingredient lists, so we can quickly find a recipe based on some ingredients we have on hand.\n", + "\n", + "The scripts used to compile this can be found at https://github.com/fictivekin/openrecipes, and the link to the current version of the database is found there as well.\n", + "\n", + "As of Spring 2016, this database is about 30 MB, and can be downloaded and unzipped with these commands:" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# !curl -O http://openrecipes.s3.amazonaws.com/recipeitems-latest.json.gz\n", + "# !gunzip recipeitems-latest.json.gz" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The database is in JSON format, so we will try ``pd.read_json`` to read it:" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "ValueError: Trailing data\n" + ] + } + ], + "source": [ + "try:\n", + " recipes = pd.read_json('recipeitems-latest.json')\n", + "except ValueError as e:\n", + " print(\"ValueError:\", e)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Oops! We get a ``ValueError`` mentioning that there is \"trailing data.\"\n", + "Searching for the text of this error on the Internet, it seems that it's due to using a file in which *each line* is itself a valid JSON, but the full file is not.\n", + "Let's check if this interpretation is true:" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(2, 12)" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "with open('recipeitems-latest.json') as f:\n", + " line = f.readline()\n", + "pd.read_json(line).shape" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Yes, apparently each line is a valid JSON, so we'll need to string them together.\n", + "One way we can do this is to actually construct a string representation containing all these JSON entries, and then load the whole thing with ``pd.read_json``:" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# read the entire file into a Python array\n", + "with open('recipeitems-latest.json', 'r') as f:\n", + " # Extract each line\n", + " data = (line.strip() for line in f)\n", + " # Reformat so each line is the element of a list\n", + " data_json = \"[{0}]\".format(','.join(data))\n", + "# read the result as a JSON\n", + "recipes = pd.read_json(data_json)" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(173278, 17)" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "recipes.shape" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We see there are nearly 200,000 recipes, and 17 columns.\n", + "Let's take a look at one row to see what we have:" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "_id {'$oid': '5160756b96cc62079cc2db15'}\n", + "cookTime PT30M\n", + "creator NaN\n", + "dateModified NaN\n", + "datePublished 2013-03-11\n", + "description Late Saturday afternoon, after Marlboro Man ha...\n", + "image http://static.thepioneerwoman.com/cooking/file...\n", + "ingredients Biscuits\\n3 cups All-purpose Flour\\n2 Tablespo...\n", + "name Drop Biscuits and Sausage Gravy\n", + "prepTime PT10M\n", + "recipeCategory NaN\n", + "recipeInstructions NaN\n", + "recipeYield 12\n", + "source thepioneerwoman\n", + "totalTime NaN\n", + "ts {'$date': 1365276011104}\n", + "url http://thepioneerwoman.com/cooking/2013/03/dro...\n", + "Name: 0, dtype: object" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "recipes.iloc[0]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "There is a lot of information there, but much of it is in a very messy form, as is typical of data scraped from the Web.\n", + "In particular, the ingredient list is in string format; we're going to have to carefully extract the information we're interested in.\n", + "Let's start by taking a closer look at the ingredients:" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "count 173278.000000\n", + "mean 244.617926\n", + "std 146.705285\n", + "min 0.000000\n", + "25% 147.000000\n", + "50% 221.000000\n", + "75% 314.000000\n", + "max 9067.000000\n", + "Name: ingredients, dtype: float64" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "recipes.ingredients.str.len().describe()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The ingredient lists average 250 characters long, with a minimum of 0 and a maximum of nearly 10,000 characters!\n", + "\n", + "Just out of curiousity, let's see which recipe has the longest ingredient list:" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'Carrot Pineapple Spice & Brownie Layer Cake with Whipped Cream & Cream Cheese Frosting and Marzipan Carrots'" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "recipes.name[np.argmax(recipes.ingredients.str.len())]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "That certainly looks like an involved recipe.\n", + "\n", + "We can do other aggregate explorations; for example, let's see how many of the recipes are for breakfast food:" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "3524" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "recipes.description.str.contains('[Bb]reakfast').sum()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Or how many of the recipes list cinnamon as an ingredient:" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "10526" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "recipes.ingredients.str.contains('[Cc]innamon').sum()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We could even look to see whether any recipes misspell the ingredient as \"cinamon\":" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "11" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "recipes.ingredients.str.contains('[Cc]inamon').sum()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This is the type of essential data exploration that is possible with Pandas string tools.\n", + "It is data munging like this that Python really excels at." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### A simple recipe recommender\n", + "\n", + "Let's go a bit further, and start working on a simple recipe recommendation system: given a list of ingredients, find a recipe that uses all those ingredients.\n", + "While conceptually straightforward, the task is complicated by the heterogeneity of the data: there is no easy operation, for example, to extract a clean list of ingredients from each row.\n", + "So we will cheat a bit: we'll start with a list of common ingredients, and simply search to see whether they are in each recipe's ingredient list.\n", + "For simplicity, let's just stick with herbs and spices for the time being:" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "spice_list = ['salt', 'pepper', 'oregano', 'sage', 'parsley',\n", + " 'rosemary', 'tarragon', 'thyme', 'paprika', 'cumin']" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can then build a Boolean ``DataFrame`` consisting of True and False values, indicating whether this ingredient appears in the list:" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
cuminoreganopaprikaparsleypepperrosemarysagesalttarragonthyme
0FalseFalseFalseFalseFalseFalseTrueFalseFalseFalse
1FalseFalseFalseFalseFalseFalseFalseFalseFalseFalse
2TrueFalseFalseFalseTrueFalseFalseTrueFalseFalse
3FalseFalseFalseFalseFalseFalseFalseFalseFalseFalse
4FalseFalseFalseFalseFalseFalseFalseFalseFalseFalse
\n", + "
" + ], + "text/plain": [ + " cumin oregano paprika parsley pepper rosemary sage salt tarragon thyme\n", + "0 False False False False False False True False False False\n", + "1 False False False False False False False False False False\n", + "2 True False False False True False False True False False\n", + "3 False False False False False False False False False False\n", + "4 False False False False False False False False False False" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import re\n", + "spice_df = pd.DataFrame(dict((spice, recipes.ingredients.str.contains(spice, re.IGNORECASE))\n", + " for spice in spice_list))\n", + "spice_df.head()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now, as an example, let's say we'd like to find a recipe that uses parsley, paprika, and tarragon.\n", + "We can compute this very quickly using the ``query()`` method of ``DataFrame``s, discussed in [High-Performance Pandas: ``eval()`` and ``query()``](03.12-Performance-Eval-and-Query.ipynb):" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "10" + ] + }, + "execution_count": 30, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "selection = spice_df.query('parsley & paprika & tarragon')\n", + "len(selection)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We find only 10 recipes with this combination; let's use the index returned by this selection to discover the names of the recipes that have this combination:" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "2069 All cremat with a Little Gem, dandelion and wa...\n", + "74964 Lobster with Thermidor butter\n", + "93768 Burton's Southern Fried Chicken with White Gravy\n", + "113926 Mijo's Slow Cooker Shredded Beef\n", + "137686 Asparagus Soup with Poached Eggs\n", + "140530 Fried Oyster Po’boys\n", + "158475 Lamb shank tagine with herb tabbouleh\n", + "158486 Southern fried chicken in buttermilk\n", + "163175 Fried Chicken Sliders with Pickles + Slaw\n", + "165243 Bar Tartine Cauliflower Salad\n", + "Name: name, dtype: object" + ] + }, + "execution_count": 31, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "recipes.name[selection.index]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now that we have narrowed down our recipe selection by a factor of almost 20,000, we are in a position to make a more informed decision about what we'd like to cook for dinner." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Going further with recipes\n", + "\n", + "Hopefully this example has given you a bit of a flavor (ba-dum!) for the types of data cleaning operations that are efficiently enabled by Pandas string methods.\n", + "Of course, building a very robust recipe recommendation system would require a *lot* more work!\n", + "Extracting full ingredient lists from each recipe would be an important piece of the task; unfortunately, the wide variety of formats used makes this a relatively time-consuming process.\n", + "This points to the truism that in data science, cleaning and munging of real-world data often comprises the majority of the work, and Pandas provides the tools that can help you do this efficiently." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "< [Pivot Tables](03.09-Pivot-Tables.ipynb) | [Contents](Index.ipynb) | [Working with Time Series](03.11-Working-with-Time-Series.ipynb) >" + ] + } + ], + "metadata": { + "anaconda-cloud": {}, + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.4.3" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/pandas/03.11-Working-with-Time-Series.ipynb b/pandas/03.11-Working-with-Time-Series.ipynb new file mode 100644 index 0000000..64ad82e --- /dev/null +++ b/pandas/03.11-Working-with-Time-Series.ipynb @@ -0,0 +1,1957 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "\n", + "*This notebook contains an excerpt from the [Python Data Science Handbook](http://shop.oreilly.com/product/0636920034919.do) by Jake VanderPlas; the content is available [on GitHub](https://github.com/jakevdp/PythonDataScienceHandbook).*\n", + "\n", + "*The text is released under the [CC-BY-NC-ND license](https://creativecommons.org/licenses/by-nc-nd/3.0/us/legalcode), and code is released under the [MIT license](https://opensource.org/licenses/MIT). If you find this content useful, please consider supporting the work by [buying the book](http://shop.oreilly.com/product/0636920034919.do)!*\n", + "\n", + "*No changes were made to the contents of this notebook from the original.*" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "< [Vectorized String Operations](03.10-Working-With-Strings.ipynb) | [Contents](Index.ipynb) | [High-Performance Pandas: eval() and query()](03.12-Performance-Eval-and-Query.ipynb) >" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Working with Time Series" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Pandas was developed in the context of financial modeling, so as you might expect, it contains a fairly extensive set of tools for working with dates, times, and time-indexed data.\n", + "Date and time data comes in a few flavors, which we will discuss here:\n", + "\n", + "- *Time stamps* reference particular moments in time (e.g., July 4th, 2015 at 7:00am).\n", + "- *Time intervals* and *periods* reference a length of time between a particular beginning and end point; for example, the year 2015. Periods usually reference a special case of time intervals in which each interval is of uniform length and does not overlap (e.g., 24 hour-long periods comprising days).\n", + "- *Time deltas* or *durations* reference an exact length of time (e.g., a duration of 22.56 seconds).\n", + "\n", + "In this section, we will introduce how to work with each of these types of date/time data in Pandas.\n", + "This short section is by no means a complete guide to the time series tools available in Python or Pandas, but instead is intended as a broad overview of how you as a user should approach working with time series.\n", + "We will start with a brief discussion of tools for dealing with dates and times in Python, before moving more specifically to a discussion of the tools provided by Pandas.\n", + "After listing some resources that go into more depth, we will review some short examples of working with time series data in Pandas." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Dates and Times in Python\n", + "\n", + "The Python world has a number of available representations of dates, times, deltas, and timespans.\n", + "While the time series tools provided by Pandas tend to be the most useful for data science applications, it is helpful to see their relationship to other packages used in Python." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Native Python dates and times: ``datetime`` and ``dateutil``\n", + "\n", + "Python's basic objects for working with dates and times reside in the built-in ``datetime`` module.\n", + "Along with the third-party ``dateutil`` module, you can use it to quickly perform a host of useful functionalities on dates and times.\n", + "For example, you can manually build a date using the ``datetime`` type:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "datetime.datetime(2015, 7, 4, 0, 0)" + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from datetime import datetime\n", + "datetime(year=2015, month=7, day=4)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Or, using the ``dateutil`` module, you can parse dates from a variety of string formats:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "datetime.datetime(2015, 7, 4, 0, 0)" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from dateutil import parser\n", + "date = parser.parse(\"4th of July, 2015\")\n", + "date" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": false + }, + "source": [ + "Once you have a ``datetime`` object, you can do things like printing the day of the week:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'Saturday'" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "date.strftime('%A')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In the final line, we've used one of the standard string format codes for printing dates (``\"%A\"``), which you can read about in the [strftime section](https://docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior) of Python's [datetime documentation](https://docs.python.org/3/library/datetime.html).\n", + "Documentation of other useful date utilities can be found in [dateutil's online documentation](http://labix.org/python-dateutil).\n", + "A related package to be aware of is [``pytz``](http://pytz.sourceforge.net/), which contains tools for working with the most migrane-inducing piece of time series data: time zones.\n", + "\n", + "The power of ``datetime`` and ``dateutil`` lie in their flexibility and easy syntax: you can use these objects and their built-in methods to easily perform nearly any operation you might be interested in.\n", + "Where they break down is when you wish to work with large arrays of dates and times:\n", + "just as lists of Python numerical variables are suboptimal compared to NumPy-style typed numerical arrays, lists of Python datetime objects are suboptimal compared to typed arrays of encoded dates." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Typed arrays of times: NumPy's ``datetime64``\n", + "\n", + "The weaknesses of Python's datetime format inspired the NumPy team to add a set of native time series data type to NumPy.\n", + "The ``datetime64`` dtype encodes dates as 64-bit integers, and thus allows arrays of dates to be represented very compactly.\n", + "The ``datetime64`` requires a very specific input format:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array(datetime.date(2015, 7, 4), dtype='datetime64[D]')" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import numpy as np\n", + "date = np.array('2015-07-04', dtype=np.datetime64)\n", + "date" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Once we have this date formatted, however, we can quickly do vectorized operations on it:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array(['2015-07-04', '2015-07-05', '2015-07-06', '2015-07-07',\n", + " '2015-07-08', '2015-07-09', '2015-07-10', '2015-07-11',\n", + " '2015-07-12', '2015-07-13', '2015-07-14', '2015-07-15'], dtype='datetime64[D]')" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "date + np.arange(12)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Because of the uniform type in NumPy ``datetime64`` arrays, this type of operation can be accomplished much more quickly than if we were working directly with Python's ``datetime`` objects, especially as arrays get large\n", + "(we introduced this type of vectorization in [Computation on NumPy Arrays: Universal Functions](02.03-Computation-on-arrays-ufuncs.ipynb)).\n", + "\n", + "One detail of the ``datetime64`` and ``timedelta64`` objects is that they are built on a *fundamental time unit*.\n", + "Because the ``datetime64`` object is limited to 64-bit precision, the range of encodable times is $2^{64}$ times this fundamental unit.\n", + "In other words, ``datetime64`` imposes a trade-off between *time resolution* and *maximum time span*.\n", + "\n", + "For example, if you want a time resolution of one nanosecond, you only have enough information to encode a range of $2^{64}$ nanoseconds, or just under 600 years.\n", + "NumPy will infer the desired unit from the input; for example, here is a day-based datetime:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "numpy.datetime64('2015-07-04')" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.datetime64('2015-07-04')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here is a minute-based datetime:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "numpy.datetime64('2015-07-04T12:00')" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.datetime64('2015-07-04 12:00')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Notice that the time zone is automatically set to the local time on the computer executing the code.\n", + "You can force any desired fundamental unit using one of many format codes; for example, here we'll force a nanosecond-based time:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "numpy.datetime64('2015-07-04T12:59:59.500000000')" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.datetime64('2015-07-04 12:59:59.50', 'ns')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The following table, drawn from the [NumPy datetime64 documentation](http://docs.scipy.org/doc/numpy/reference/arrays.datetime.html), lists the available format codes along with the relative and absolute timespans that they can encode:" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "|Code | Meaning | Time span (relative) | Time span (absolute) |\n", + "|--------|-------------|----------------------|------------------------|\n", + "| ``Y`` | Year\t | ± 9.2e18 years | [9.2e18 BC, 9.2e18 AD] |\n", + "| ``M`` | Month | ± 7.6e17 years | [7.6e17 BC, 7.6e17 AD] |\n", + "| ``W`` | Week\t | ± 1.7e17 years | [1.7e17 BC, 1.7e17 AD] |\n", + "| ``D`` | Day | ± 2.5e16 years | [2.5e16 BC, 2.5e16 AD] |\n", + "| ``h`` | Hour | ± 1.0e15 years | [1.0e15 BC, 1.0e15 AD] |\n", + "| ``m`` | Minute | ± 1.7e13 years | [1.7e13 BC, 1.7e13 AD] |\n", + "| ``s`` | Second | ± 2.9e12 years | [ 2.9e9 BC, 2.9e9 AD] |\n", + "| ``ms`` | Millisecond | ± 2.9e9 years | [ 2.9e6 BC, 2.9e6 AD] |\n", + "| ``us`` | Microsecond | ± 2.9e6 years | [290301 BC, 294241 AD] |\n", + "| ``ns`` | Nanosecond | ± 292 years | [ 1678 AD, 2262 AD] |\n", + "| ``ps`` | Picosecond | ± 106 days | [ 1969 AD, 1970 AD] |\n", + "| ``fs`` | Femtosecond | ± 2.6 hours | [ 1969 AD, 1970 AD] |\n", + "| ``as`` | Attosecond | ± 9.2 seconds | [ 1969 AD, 1970 AD] |" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For the types of data we see in the real world, a useful default is ``datetime64[ns]``, as it can encode a useful range of modern dates with a suitably fine precision.\n", + "\n", + "Finally, we will note that while the ``datetime64`` data type addresses some of the deficiencies of the built-in Python ``datetime`` type, it lacks many of the convenient methods and functions provided by ``datetime`` and especially ``dateutil``.\n", + "More information can be found in [NumPy's datetime64 documentation](http://docs.scipy.org/doc/numpy/reference/arrays.datetime.html)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Dates and times in pandas: best of both worlds\n", + "\n", + "Pandas builds upon all the tools just discussed to provide a ``Timestamp`` object, which combines the ease-of-use of ``datetime`` and ``dateutil`` with the efficient storage and vectorized interface of ``numpy.datetime64``.\n", + "From a group of these ``Timestamp`` objects, Pandas can construct a ``DatetimeIndex`` that can be used to index data in a ``Series`` or ``DataFrame``; we'll see many examples of this below.\n", + "\n", + "For example, we can use Pandas tools to repeat the demonstration from above.\n", + "We can parse a flexibly formatted string date, and use format codes to output the day of the week:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Timestamp('2015-07-04 00:00:00')" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import pandas as pd\n", + "date = pd.to_datetime(\"4th of July, 2015\")\n", + "date" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'Saturday'" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "date.strftime('%A')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Additionally, we can do NumPy-style vectorized operations directly on this same object:" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "DatetimeIndex(['2015-07-04', '2015-07-05', '2015-07-06', '2015-07-07',\n", + " '2015-07-08', '2015-07-09', '2015-07-10', '2015-07-11',\n", + " '2015-07-12', '2015-07-13', '2015-07-14', '2015-07-15'],\n", + " dtype='datetime64[ns]', freq=None)" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "date + pd.to_timedelta(np.arange(12), 'D')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In the next section, we will take a closer look at manipulating time series data with the tools provided by Pandas." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Pandas Time Series: Indexing by Time\n", + "\n", + "Where the Pandas time series tools really become useful is when you begin to *index data by timestamps*.\n", + "For example, we can construct a ``Series`` object that has time indexed data:" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "2014-07-04 0\n", + "2014-08-04 1\n", + "2015-07-04 2\n", + "2015-08-04 3\n", + "dtype: int64" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "index = pd.DatetimeIndex(['2014-07-04', '2014-08-04',\n", + " '2015-07-04', '2015-08-04'])\n", + "data = pd.Series([0, 1, 2, 3], index=index)\n", + "data" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now that we have this data in a ``Series``, we can make use of any of the ``Series`` indexing patterns we discussed in previous sections, passing values that can be coerced into dates:" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "2014-07-04 0\n", + "2014-08-04 1\n", + "2015-07-04 2\n", + "dtype: int64" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data['2014-07-04':'2015-07-04']" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "There are additional special date-only indexing operations, such as passing a year to obtain a slice of all data from that year:" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "2015-07-04 2\n", + "2015-08-04 3\n", + "dtype: int64" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data['2015']" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Later, we will see additional examples of the convenience of dates-as-indices.\n", + "But first, a closer look at the available time series data structures." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Pandas Time Series Data Structures\n", + "\n", + "This section will introduce the fundamental Pandas data structures for working with time series data:\n", + "\n", + "- For *time stamps*, Pandas provides the ``Timestamp`` type. As mentioned before, it is essentially a replacement for Python's native ``datetime``, but is based on the more efficient ``numpy.datetime64`` data type. The associated Index structure is ``DatetimeIndex``.\n", + "- For *time Periods*, Pandas provides the ``Period`` type. This encodes a fixed-frequency interval based on ``numpy.datetime64``. The associated index structure is ``PeriodIndex``.\n", + "- For *time deltas* or *durations*, Pandas provides the ``Timedelta`` type. ``Timedelta`` is a more efficient replacement for Python's native ``datetime.timedelta`` type, and is based on ``numpy.timedelta64``. The associated index structure is ``TimedeltaIndex``." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The most fundamental of these date/time objects are the ``Timestamp`` and ``DatetimeIndex`` objects.\n", + "While these class objects can be invoked directly, it is more common to use the ``pd.to_datetime()`` function, which can parse a wide variety of formats.\n", + "Passing a single date to ``pd.to_datetime()`` yields a ``Timestamp``; passing a series of dates by default yields a ``DatetimeIndex``:" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "DatetimeIndex(['2015-07-03', '2015-07-04', '2015-07-06', '2015-07-07',\n", + " '2015-07-08'],\n", + " dtype='datetime64[ns]', freq=None)" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dates = pd.to_datetime([datetime(2015, 7, 3), '4th of July, 2015',\n", + " '2015-Jul-6', '07-07-2015', '20150708'])\n", + "dates" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Any ``DatetimeIndex`` can be converted to a ``PeriodIndex`` with the ``to_period()`` function with the addition of a frequency code; here we'll use ``'D'`` to indicate daily frequency:" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "PeriodIndex(['2015-07-03', '2015-07-04', '2015-07-06', '2015-07-07',\n", + " '2015-07-08'],\n", + " dtype='int64', freq='D')" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dates.to_period('D')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "A ``TimedeltaIndex`` is created, for example, when a date is subtracted from another:" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "TimedeltaIndex(['0 days', '1 days', '3 days', '4 days', '5 days'], dtype='timedelta64[ns]', freq=None)" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dates - dates[0]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Regular sequences: ``pd.date_range()``\n", + "\n", + "To make the creation of regular date sequences more convenient, Pandas offers a few functions for this purpose: ``pd.date_range()`` for timestamps, ``pd.period_range()`` for periods, and ``pd.timedelta_range()`` for time deltas.\n", + "We've seen that Python's ``range()`` and NumPy's ``np.arange()`` turn a startpoint, endpoint, and optional stepsize into a sequence.\n", + "Similarly, ``pd.date_range()`` accepts a start date, an end date, and an optional frequency code to create a regular sequence of dates.\n", + "By default, the frequency is one day:" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "DatetimeIndex(['2015-07-03', '2015-07-04', '2015-07-05', '2015-07-06',\n", + " '2015-07-07', '2015-07-08', '2015-07-09', '2015-07-10'],\n", + " dtype='datetime64[ns]', freq='D')" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pd.date_range('2015-07-03', '2015-07-10')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Alternatively, the date range can be specified not with a start and endpoint, but with a startpoint and a number of periods:" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "DatetimeIndex(['2015-07-03', '2015-07-04', '2015-07-05', '2015-07-06',\n", + " '2015-07-07', '2015-07-08', '2015-07-09', '2015-07-10'],\n", + " dtype='datetime64[ns]', freq='D')" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pd.date_range('2015-07-03', periods=8)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The spacing can be modified by altering the ``freq`` argument, which defaults to ``D``.\n", + "For example, here we will construct a range of hourly timestamps:" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "DatetimeIndex(['2015-07-03 00:00:00', '2015-07-03 01:00:00',\n", + " '2015-07-03 02:00:00', '2015-07-03 03:00:00',\n", + " '2015-07-03 04:00:00', '2015-07-03 05:00:00',\n", + " '2015-07-03 06:00:00', '2015-07-03 07:00:00'],\n", + " dtype='datetime64[ns]', freq='H')" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pd.date_range('2015-07-03', periods=8, freq='H')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To create regular sequences of ``Period`` or ``Timedelta`` values, the very similar ``pd.period_range()`` and ``pd.timedelta_range()`` functions are useful.\n", + "Here are some monthly periods:" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "PeriodIndex(['2015-07', '2015-08', '2015-09', '2015-10', '2015-11', '2015-12',\n", + " '2016-01', '2016-02'],\n", + " dtype='int64', freq='M')" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pd.period_range('2015-07', periods=8, freq='M')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And a sequence of durations increasing by an hour:" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "TimedeltaIndex(['00:00:00', '01:00:00', '02:00:00', '03:00:00', '04:00:00',\n", + " '05:00:00', '06:00:00', '07:00:00', '08:00:00', '09:00:00'],\n", + " dtype='timedelta64[ns]', freq='H')" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pd.timedelta_range(0, periods=10, freq='H')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "All of these require an understanding of Pandas frequency codes, which we'll summarize in the next section." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Frequencies and Offsets\n", + "\n", + "Fundamental to these Pandas time series tools is the concept of a frequency or date offset.\n", + "Just as we saw the ``D`` (day) and ``H`` (hour) codes above, we can use such codes to specify any desired frequency spacing.\n", + "The following table summarizes the main codes available:" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "| Code | Description | Code | Description |\n", + "|--------|---------------------|--------|----------------------|\n", + "| ``D`` | Calendar day | ``B`` | Business day |\n", + "| ``W`` | Weekly | | |\n", + "| ``M`` | Month end | ``BM`` | Business month end |\n", + "| ``Q`` | Quarter end | ``BQ`` | Business quarter end |\n", + "| ``A`` | Year end | ``BA`` | Business year end |\n", + "| ``H`` | Hours | ``BH`` | Business hours |\n", + "| ``T`` | Minutes | | |\n", + "| ``S`` | Seconds | | |\n", + "| ``L`` | Milliseonds | | |\n", + "| ``U`` | Microseconds | | |\n", + "| ``N`` | nanoseconds | | |" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The monthly, quarterly, and annual frequencies are all marked at the end of the specified period.\n", + "By adding an ``S`` suffix to any of these, they instead will be marked at the beginning:" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "| Code | Description || Code | Description |\n", + "|---------|------------------------||---------|------------------------|\n", + "| ``MS`` | Month start ||``BMS`` | Business month start |\n", + "| ``QS`` | Quarter start ||``BQS`` | Business quarter start |\n", + "| ``AS`` | Year start ||``BAS`` | Business year start |" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Additionally, you can change the month used to mark any quarterly or annual code by adding a three-letter month code as a suffix:\n", + "\n", + "- ``Q-JAN``, ``BQ-FEB``, ``QS-MAR``, ``BQS-APR``, etc.\n", + "- ``A-JAN``, ``BA-FEB``, ``AS-MAR``, ``BAS-APR``, etc.\n", + "\n", + "In the same way, the split-point of the weekly frequency can be modified by adding a three-letter weekday code:\n", + "\n", + "- ``W-SUN``, ``W-MON``, ``W-TUE``, ``W-WED``, etc.\n", + "\n", + "On top of this, codes can be combined with numbers to specify other frequencies.\n", + "For example, for a frequency of 2 hours 30 minutes, we can combine the hour (``H``) and minute (``T``) codes as follows:" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "TimedeltaIndex(['00:00:00', '02:30:00', '05:00:00', '07:30:00', '10:00:00',\n", + " '12:30:00', '15:00:00', '17:30:00', '20:00:00'],\n", + " dtype='timedelta64[ns]', freq='150T')" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pd.timedelta_range(0, periods=9, freq=\"2H30T\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "All of these short codes refer to specific instances of Pandas time series offsets, which can be found in the ``pd.tseries.offsets`` module.\n", + "For example, we can create a business day offset directly as follows:" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "DatetimeIndex(['2015-07-01', '2015-07-02', '2015-07-03', '2015-07-06',\n", + " '2015-07-07'],\n", + " dtype='datetime64[ns]', freq='B')" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from pandas.tseries.offsets import BDay\n", + "pd.date_range('2015-07-01', periods=5, freq=BDay())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For more discussion of the use of frequencies and offsets, see the [\"DateOffset\" section](http://pandas.pydata.org/pandas-docs/stable/timeseries.html#dateoffset-objects) of the Pandas documentation." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Resampling, Shifting, and Windowing\n", + "\n", + "The ability to use dates and times as indices to intuitively organize and access data is an important piece of the Pandas time series tools.\n", + "The benefits of indexed data in general (automatic alignment during operations, intuitive data slicing and access, etc.) still apply, and Pandas provides several additional time series-specific operations.\n", + "\n", + "We will take a look at a few of those here, using some stock price data as an example.\n", + "Because Pandas was developed largely in a finance context, it includes some very specific tools for financial data.\n", + "For example, the accompanying ``pandas-datareader`` package (installable via ``conda install pandas-datareader``), knows how to import financial data from a number of available sources, including Yahoo finance, Google Finance, and others.\n", + "Here we will load Google's closing price history:" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
OpenHighLowCloseVolume
Date
2004-08-1949.9651.9847.9350.12NaN
2004-08-2050.6954.4950.2054.10NaN
2004-08-2355.3256.6854.4754.65NaN
2004-08-2455.5655.7451.7352.38NaN
2004-08-2552.4353.9551.8952.95NaN
\n", + "
" + ], + "text/plain": [ + " Open High Low Close Volume\n", + "Date \n", + "2004-08-19 49.96 51.98 47.93 50.12 NaN\n", + "2004-08-20 50.69 54.49 50.20 54.10 NaN\n", + "2004-08-23 55.32 56.68 54.47 54.65 NaN\n", + "2004-08-24 55.56 55.74 51.73 52.38 NaN\n", + "2004-08-25 52.43 53.95 51.89 52.95 NaN" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from pandas_datareader import data\n", + "\n", + "goog = data.DataReader('GOOG', start='2004', end='2016',\n", + " data_source='google')\n", + "goog.head()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For simplicity, we'll use just the closing price:" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "goog = goog['Close']" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can visualize this using the ``plot()`` method, after the normal Matplotlib setup boilerplate (see [Chapter 4](04.00-Introduction-To-Matplotlib.ipynb)):" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%matplotlib inline\n", + "import matplotlib.pyplot as plt\n", + "import seaborn; seaborn.set()" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "goog.plot();" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Resampling and converting frequencies\n", + "\n", + "One common need for time series data is resampling at a higher or lower frequency.\n", + "This can be done using the ``resample()`` method, or the much simpler ``asfreq()`` method.\n", + "The primary difference between the two is that ``resample()`` is fundamentally a *data aggregation*, while ``asfreq()`` is fundamentally a *data selection*.\n", + "\n", + "Taking a look at the Google closing price, let's compare what the two return when we down-sample the data.\n", + "Here we will resample the data at the end of business year:" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "goog.plot(alpha=0.5, style='-')\n", + "goog.resample('BA').mean().plot(style=':')\n", + "goog.asfreq('BA').plot(style='--');\n", + "plt.legend(['input', 'resample', 'asfreq'],\n", + " loc='upper left');" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Notice the difference: at each point, ``resample`` reports the *average of the previous year*, while ``asfreq`` reports the *value at the end of the year*." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For up-sampling, ``resample()`` and ``asfreq()`` are largely equivalent, though resample has many more options available.\n", + "In this case, the default for both methods is to leave the up-sampled points empty, that is, filled with NA values.\n", + "Just as with the ``pd.fillna()`` function discussed previously, ``asfreq()`` accepts a ``method`` argument to specify how values are imputed.\n", + "Here, we will resample the business day data at a daily frequency (i.e., including weekends):" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax = plt.subplots(2, sharex=True)\n", + "data = goog.iloc[:10]\n", + "\n", + "data.asfreq('D').plot(ax=ax[0], marker='o')\n", + "\n", + "data.asfreq('D', method='bfill').plot(ax=ax[1], style='-o')\n", + "data.asfreq('D', method='ffill').plot(ax=ax[1], style='--o')\n", + "ax[1].legend([\"back-fill\", \"forward-fill\"]);" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The top panel is the default: non-business days are left as NA values and do not appear on the plot.\n", + "The bottom panel shows the differences between two strategies for filling the gaps: forward-filling and backward-filling." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Time-shifts\n", + "\n", + "Another common time series-specific operation is shifting of data in time.\n", + "Pandas has two closely related methods for computing this: ``shift()`` and ``tshift()``\n", + "In short, the difference between them is that ``shift()`` *shifts the data*, while ``tshift()`` *shifts the index*.\n", + "In both cases, the shift is specified in multiples of the frequency.\n", + "\n", + "Here we will both ``shift()`` and ``tshift()`` by 900 days; " + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax = plt.subplots(3, sharey=True)\n", + "\n", + "# apply a frequency to the data\n", + "goog = goog.asfreq('D', method='pad')\n", + "\n", + "goog.plot(ax=ax[0])\n", + "goog.shift(900).plot(ax=ax[1])\n", + "goog.tshift(900).plot(ax=ax[2])\n", + "\n", + "# legends and annotations\n", + "local_max = pd.to_datetime('2007-11-05')\n", + "offset = pd.Timedelta(900, 'D')\n", + "\n", + "ax[0].legend(['input'], loc=2)\n", + "ax[0].get_xticklabels()[2].set(weight='heavy', color='red')\n", + "ax[0].axvline(local_max, alpha=0.3, color='red')\n", + "\n", + "ax[1].legend(['shift(900)'], loc=2)\n", + "ax[1].get_xticklabels()[2].set(weight='heavy', color='red')\n", + "ax[1].axvline(local_max + offset, alpha=0.3, color='red')\n", + "\n", + "ax[2].legend(['tshift(900)'], loc=2)\n", + "ax[2].get_xticklabels()[1].set(weight='heavy', color='red')\n", + "ax[2].axvline(local_max + offset, alpha=0.3, color='red');" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We see here that ``shift(900)`` shifts the *data* by 900 days, pushing some of it off the end of the graph (and leaving NA values at the other end), while ``tshift(900)`` shifts the *index values* by 900 days.\n", + "\n", + "A common context for this type of shift is in computing differences over time. For example, we use shifted values to compute the one-year return on investment for Google stock over the course of the dataset:" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "ROI = 100 * (goog.tshift(-365) / goog - 1)\n", + "ROI.plot()\n", + "plt.ylabel('% Return on Investment');" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This helps us to see the overall trend in Google stock: thus far, the most profitable times to invest in Google have been (unsurprisingly, in retrospect) shortly after its IPO, and in the middle of the 2009 recession." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Rolling windows\n", + "\n", + "Rolling statistics are a third type of time series-specific operation implemented by Pandas.\n", + "These can be accomplished via the ``rolling()`` attribute of ``Series`` and ``DataFrame`` objects, which returns a view similar to what we saw with the ``groupby`` operation (see [Aggregation and Grouping](03.08-Aggregation-and-Grouping.ipynb)).\n", + "This rolling view makes available a number of aggregation operations by default.\n", + "\n", + "For example, here is the one-year centered rolling mean and standard deviation of the Google stock prices:" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAeQAAAFkCAYAAADxHkghAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzs3XtgXGWd+P/3OXO/ZXJPm7RpekmBSrHaAtVCrYBS/SIo\nUpVq1ZUvCuIFuvoF9wtWwRXZVbu/ddlVREUDSrsC8pUVkYqKUpWL1FJKS9uk16S5TiZzv53z+2My\nk5nMJDOZ3NPP6x+SM2cmZ54O8znP83yez6Pouq4jhBBCiGmlTvcFCCGEEEICshBCCDEjSEAWQggh\nZgAJyEIIIcQMIAFZCCGEmAEkIAshhBAzgLHQCfF4nFtvvZVTp05hNBq56667MBgM3HbbbaiqSnNz\nM9u2bQNg586d7NixA5PJxA033MCGDRsm+/qFEEKIOaFgQP7DH/6Apmk8/PDD7N69m+3btxOLxdi6\ndStr1qxh27Zt7Nq1i1WrVtHS0sJjjz1GOBzm2muvZd26dZhMpql4H0IIIcSsVnDIuqmpiUQiga7r\n+Hw+jEYj+/fvZ82aNQCsX7+e3bt3s3fvXlavXo3RaMTpdNLU1MTBgwcn/Q0IIYQQc0HBHrLD4eDk\nyZNs3LiR/v5+vvvd7/Liiy9mPe73+wkEArhcrvRxu92Oz+ebnKsWQggh5piCAfmBBx7g4osv5pZb\nbqGzs5MtW7YQi8XSjwcCAcrKynA6nfj9/pzjo9F1HUVRxnH5QgghxNxQMCC73W6MxuRpLpeLeDzO\nihUreP7557ngggt49tlnWbt2LStXrmT79u1Eo1EikQitra00NzeP+tqKotDdPfd60TU1rjn5viab\ntFvppO1KI+1WOmm70tTUuEZ8rGBA/tjHPsY//dM/8eEPf5h4PM4XvvAF3vCGN3D77bcTi8VYunQp\nGzduRFEUtmzZwubNm9F1na1bt2I2myf0jQghhBBzlTLduz3NxTssuXMsjbRb6aTtSiPtVjppu9KM\n1kOWwiBCCCHEDCABWQghhJgBJCALIYQQM4AEZCGEEGIGkIAshBBCTIEuT3DUxyUgCyGEEFOgvUcC\n8pj99a9/5pe//MW4XycajfLEE+N/HSGEEHNfwcIg02nnM4d54UDXhL7m+WfX8oFLlo16zoUXvmVC\n/lZvbw+//OXjXHHFeyfk9YQQQswu8YSGLxjD7ShcKGtGB+Tp8uSTT/CXv+yms/M0tbV1nDp1khUr\nzuUf//FWfvjD+zh27Cj9/R58Ph+33PJFVq58I1dddTmPP/4UAFu3buVd77qKp556kmPH2njggfv5\n+Mf/9zS/KyGEEFNt/9E+NA3s1sLhdkYH5A9csqxgb3YynTx5nH/7t//EbDbzgQ9chcdzPQA2m42v\nfvXrtLW18tWv3s4DD/wUyN0k42Mf+wRtbUckGAshxBlK05L/DYbjBc+d0QF5ujU0LMRqtQJQXV1D\nJBIF4M1vPh+AxYuX4PH0Dp49VIF0mquRCiGEmIUkqWsUmVtDZgbZgwdfA6C19TDV1bUAJBIJwuEw\nsViMw4cPp5+fSCSm8IqFEELMFPGENqbzpYc8guH7NGf+fujQQT7/+U8TiYS57bbbAdi06Vo+9amP\nU1/fQENDAwAVFZUkEnG++93/4IYbPjN1Fy+EEGLanez2j+l82e1pjH74w/uoqqrmqquuHvEc2QWl\nNNJupZO2K420W+mk7Qrbc6gn59g73rp4xPNlyHqMhvechRBCiIkgQ9Zj9A//cP10X4IQQog5SHrI\nQgghxCQwm8YWYiUgCyGEEJNgrBOcEpCFEEKISRCJjW3ZkwRkIYQQYoJlrkGuq7QV9RwJyHPcVVdd\nDsBnP/spjh8/xpNPPsFzz/1xmq9KCCHmLl3X2dfaB4DFbGBepZ2zGss5b1nVqM+b8VnWd+y+O+/x\nu976pQk5f+7LnsV417uumKbrEEKIM4M3EE3/bDapKIqCzTLLN5eYDvF4nLvv/irt7afQNJ0PfvDD\nXHLJZXz2s5+iuXk5ra1HCAaD3HXXN6irm8cjj+zg6aefQlEULrvsnbz//R/Mer3vfe9eampqufrq\nTfh8Pm6++dP84ActfO9797J37x40LcEHP/hhNmy4lD17/saPfvR9dF0nFAqybds/YzQa+T//52bK\nyytYu3YdmzdvSb/2+99/BU1NS2hqWsymTR/i7rvvJJFIoCgKN9/8RZYuzd2Y44c/vI/KyioWLWri\noYd+jMlkor29nUsvfQcf/egnOHXqJP/8z1/BZDJRVzePjo52vvOd7+Vtq2Rv+1kikQi9vb1s2vQh\n/vjHP9DWdoSbbrqZiy5azzPP7GLnzp9iMBg477xVfOpTN9Hd3cU3v3k3sViM3t4err/+Ri666G1c\neeWVrFy5isOHD6GqKt/4xrew2x0T+w8shBCTLBQZ2kgiVMSmEikzPiCPtWc73p7w448/Snl5JXfc\ncRfBYJDrrvsIq1evAWDFinP53Of+kfvu+0927XqKdevW89vfPs1//dcP0HWdW265iQsueAs1NW9I\nv9573vNevvKV/8vVV2/i6ad/zeWXv4u//GU37e2nuPfe7xONRvnUpz7O+edfSFtbK1/+8l1UVVXT\n0vIjfve7XbzjHRvxeDz86EfJoJapp6ebBx74GS6Xi9tvv5UPfGAz69ZdzKFDr3P33Xdy//0/yfse\nU8VNOjtP85Of7CASifDe927kox/9BPfe+//xsY9dx4UXvoVf/vIXnD7dMWp7BYMhvv3t7/Db3/6G\nnTt/xve+9yP+9rcX+fnPd3Deeav44Q/v4wc/aMFisXDXXV/mxRefB+Daa7ewatWb2bdvLz/84X1c\ndNHb8Pv9vOMd7+Lmm7/InXfewZ//vJtLL31Hyf+WQggxHTLrX8YTxRfDnPEBeaodO9bG+edfCIDd\nbqepaTGnTp0EYPnyswCora3D4+mjtfUIp0938PnP34iu6/j9Pk6ePM59930Hr9fHkiXLuPnmL+Bw\nODh6tI2nn36Se+7ZzhNPPM7Bgwf43OduQNd1EokEHR0d1NTUsH37v2K32+nu7uK881YBMH9+fU4w\nBnC7y3G5XOnrfuMb3wRAc/Nyurs7C77XJUuWoSgKVqsVi8Wafp1zz10JwBvfuIqnn/71qK+RahOn\n08WiRU0AuFxlRKMRTp06QX+/hy9+8fODvf4Qp06d5LzzVvHjH/+AJ554HEiOSqQ0Ny9Pt3E0Gin4\nHoQQYqbRSqxILQF5mEWLFrNnz8tcfPEGgsEAra1HqK9fMPho9nxsY+MilixZyje/+e8A7Nz5U5Yu\nbea73/1uVo3X97znfTzwwP3U1tZRVuamsbGJ1avX8MUv/hO6rvPjH/+A+voGbrnlJnbufBybzcY/\n//NX0jtMjVSuM/NwU9MS9uz5GxddtJ5Dhw5SWZlKHij2g5E8b8mSZbzyyl7Wrn0r+/a9UvBZo5US\nra9voK5uHtu334vBYODJJ5+gufks7r//v7jyyqu58MK38Ktf/ZInn3yiqNcTQojZQNOGvncdtuLD\nrATkYa666mruuedrfPrT/5toNMonPvFJysvL8waKZcuaefObz+fGG68jFouxYsUbqKmpzTlv/foN\nfPvb97Bt29cAuOii9bz88kvcdNP1hEIh1q/fgN1u5/LL382nP30dNpudyspKenq6gdGC1NDxm276\nPPfc8zUefvhBEok4X/rSl7POSb1G5mtlv27y5xtu+Ax3330nDz/8IA6HA6Ox9I+I213OBz+4mc98\n5noSCY358+u55JJ38Pa3X8Z//Md2Wlp+RE1NLQMD3gLXJoQQs0ciIyAbDcUvZpLdnibB8F1QwuEw\nn/3sp/j+9388jVdVnN/85te84Q3n0tCwgCee+AX79r3CbbfdMSV/W3aPKZ20XWmk3UonbZdfLJ7g\n1TZP+veacisNNc6h32tcIz5XesiTbN++vfzrv36dT3ziU9N9KUWpq6tj27Z/wmq1YjAYuO22O/jW\nt+7h6NHWdK9V13UUReGb3/x3zGbzNF+xEELMHP3+oSVPtRU2asqLKwoC0kOeFHLnWBppt9JJ25VG\n2q100nb5Ze6BvKq5Oufx0XrIUqlLCCGEmAEKDlk/9thjPProoyiKQiQS4cCBAzz00EN8/etfR1VV\nmpub2bZtGwA7d+5kx44dmEwmbrjhBjZs2DDZ1y+EEELMGGUOMwOBKE3zR+4Jj6RgQH7f+97H+973\nPgDuvPNOrrnmGu699162bt3KmjVr2LZtG7t27WLVqlW0tLTw2GOPEQ6Hufbaa1m3bh0mk2ns70gI\nIYSYhVILRCym3NoRhRQ9ZP3KK69w+PBhNm3axKuvvsqaNcnqVevXr2f37t3s3buX1atXYzQacTqd\nNDU1cfDgwTFfkBBCCDFbxeLJXZ4M6tiXbhadZX3ffffx2c9+Nue4w+HA7/cTCATSVaMgWeXK5ys8\n4T/aBPdsNlPe10UXXcSf/vQntmzZwp133smePXsoLy/n7W9/+6T9zYceeogPf/jDWcei0SgbN27k\nmWeeGfW5M6XdZiNpu9JIu5VO2i5XbzCGyR9l/jw36hiDclEB2efzcfToUc4//3wAVHWoYx0IBCgr\nK8PpdOL3+3OOF1IoS6/11n9kyT3fmrDfp8JMyj7UNJ3ubh+xWIK+vgAXXXQZMLnZ7ffeey/vfOeV\nWccikQiaNvrfnUntNttI25VG2q100nb5eTxB/MEYPT2+vAWOxr0O+YUXXmDt2rXp38855xxeeOEF\nzj//fJ599lnWrl3LypUr2b59O9FolEgkQmtrK83NzSW8nekluz0Vv9vTiRPH+frXv4rRaETXdbZt\n+xpPPvkEAwMDfPvb93DjjZ/jzjtvx+fz0dCwIO9rCCHEnDK4kLiUaoNFBeS2tjYWLlyY/v3WW2/l\njjvuIBaLsXTpUjZu3IiiKGzZsoXNmzej6zpbt26dkKIRw3u34/29ENntqfjdnl544a+sWHEun/70\n5/j731/G7/fz0Y9+gkce2cnWrbfys589yJIly7j++hvZv38ff/vbS2P6txBCiNlGL3r/gFxFBeTr\nrrsu6/empiZaWlpyztu0aRObNm0q+WJmAtntqfjdnq644ioeeujHbN36WVwuJ5/85E1Zj584cYy3\nvvViIHkzYzSOPetQCCFmnRJL8UvpzGFkt6fid3v64x//wBvf+Cb+4R+uZ9eup3jooR/zpS99OX3d\nTU1L2LdvLxddtJ7XXz9APJ4o8lqEEGJ20vWS47EE5OFkt6fid3s6++xz0vPNmqbxuc/9IwCLFy/h\nrru+zG233cFdd32Zm266nsbGRZjNsiZdCDH3lbpZndSyngSy21NpJGuzdNJ2pZF2K520XX4Hj3uI\nxDTOW1qV93HZ7WkayW5PQghxZpEe8gwid46lkXYrnbRdaaTdSnemtV0kmsBkUlELRNsDxzzEEhor\nl4y9hyy7PQkhhBCjCIbjvHbMQ3t3oOC5OqUndUlAFkIIIUYRjsYB6PGGC588jjRrmUMWQgghRlHs\nRhGarhOJaSX/HekhCyGEEKNQigzIRfWgRyEBWQghhChSKBJnz6EeTnb5cx7rlYAshBBCTKKMtUgH\nj/cD+XvDJWyBnP388T1dCCGEEADaOBcRS0AWQgghRpEZZ03GkcNmNDa+ev0SkIUQQogiWc0j71o3\n3jJbEpCFEEKI0WRE2sygq01woUsJyEIIIUSRsoJwxo/+UGzcry2FQYQQQogiBcPx9M+aruMPxPCH\nYnR5QuN+bQnIQgghxChGG5hubR/IOWa3lhZaJSALIYQQoxhpqtjji+Qcq6mwUV9lL+nvyByyEEII\nUYJTeXZ/qq+yp/eOHysJyEIIIcQEUBRKDsYgAVkIIYSYEOMJxiABWQghhJgQUstaCCGEmET6sKyu\nMoc573nxxPgKhUhAFkIIIcbAbMofOt3O/IG6WBKQhRBCiCI4bEbOW1bFSCPThnGOWUtAFkIIIYpQ\nVWZFHSVxa7THiiEBWQghhBhFTmGQEQLvOOOxBGQhhBBiJpDSmUIIISbEqW4/3f1h6msc1Jbbpvty\nJlx6nfEItTTHm2VdVEC+7777eOaZZ4jFYmzevJnzzz+f2267DVVVaW5uZtu2bQDs3LmTHTt2YDKZ\nuOGGG9iwYcO4Lk4IIcTs0d0fBqC9O0C5w4zZZJjmK5oY+rDtJSzD3pfRqBCPj39v5IJD1s8//zwv\nv/wyDz/8MC0tLXR0dHD33XezdetWHnzwQTRNY9euXfT09NDS0sKOHTu4//77+da3vkUsNv79IYUQ\nQsx8J7v8Wb/vP+ohFk9M09VMsAKxVhkx73psCgbkP/3pTyxfvpxPf/rT3HjjjWzYsIH9+/ezZs0a\nANavX8/u3bvZu3cvq1evxmg04nQ6aWpq4uDBgxNykUIIIWa2Hm8451goOkcC8nAjxN/xJnUVHLL2\neDy0t7fzve99jxMnTnDjjTeiaVr6cYfDgd/vJxAI4HK50sftdjs+n298VyeEEGLGiye0vMd1bfzD\nuDNB6l2kAu5E9YiHKxiQy8vLWbp0KUajkcWLF2OxWOjs7Ew/HggEKCsrw+l04vf7c44XUlPjKnjO\nbDRX39dkk3YrnbRdaaTdSpdqu1AkjtsdwmYxMq/KQVu7F4CKSgdV7uKSuzRN59AJD9Xltpzn9HpD\neAYiLG5wj7v4xlh85y8/otHdwAU1b8Uf1aiqclJZZkU3GhiIJHv/86sddPeHiMc1Kits4/o8FQzI\nq1evpqWlhY9//ON0dnYSCoVYu3Ytzz//PBdccAHPPvssa9euZeXKlWzfvp1oNEokEqG1tZXm5uaC\nF9DdPfd60TU1rjn5viabtFvppO1KI+1Wusy26+gN4PWGCJtU3FYDXm8IgB6rAS0aL+r1uvpDtHcH\nOH7Ky6rm6qzH9hzqAcCgazhtpgl8FyM74TvFH489z9kVzSwzrsLrDdFnN5KIxPAMhNPvsanGjhJP\n4PWGcZjVgp+n0QJ2wYC8YcMGXnzxRa655hp0XecrX/kKDQ0N3H777cRiMZYuXcrGjRtRFIUtW7aw\nefNmdF1n69atmM3jq+sphBBiZtM0nc6+UPr3zGpVvmCMyjJrUa/j9UeyXlMd7AlHYoms41Plt8f/\nCMAljetHPU9RFOZV2XHYTOOuZV3UsqcvfOELOcdaWlpyjm3atIlNmzaN64KEEELMHqf7gumf51U5\nUDNShbUR1uvmo2YMRbf3BJhXZUdVFV476kkfD0biI+60NJH6I15e6trDPEcdKyqX0z0sYW34vsdG\ng0qFyzLuvyuFQYQQQpTMG4imf47GEyjK0JBysQHZH4oRjgz1hHu8YXq8YWyW7PW+p3uDzKu0j/OK\nC/v9iefQdI1LF16cDL6p9zHeNOoCpHSmEEKIkmiaTiRjaVNVmRWDqmC3Jvt6xcTjWDzB4ZNeYvGh\nTG2DIRn4QpHpWTbVFezGZXJyft2bpvTvSg9ZCCFESU4MKwZiNCT7eMsXlvP3wz1Fzfn6grkFpOwW\nY97jU+X6lR+lP+LFZEj29tPLngb/axncD9lqnthKZBKQhRBCjJmu63h8kREfVxQFvYgu8vFOf86x\nkdY1Q3J4e7IzrRVFocJaPuLjdquJpQ1l2CwTG0JlyFoIIcSYDWTMHeejqlBqUvRoQ9WHT3pLe1Gg\npz9ER29g7E8c3kUGXHZzekRgokhAFkIIMWa+4OgBWVGUgkldxfSgJ9LJ7gCdfaEx/93U+1AlqUsI\nIcRM094zek9TVRRiMS0rC3u4YuOiy5E9RF3KphWZNwdd/SGOd2YX8IhpxRUwmUwSkIUQQoxJPKEV\n3AEptay4rX0g57GEpqHpenpbQ5NRxWBQOHdJZd7XWlrvzlp/XErHOrNX3NETpG8gQmJwX4bOYDf/\n97mv8fSx34/w3OR/J7mDLAFZCCHE2OTLnjabRg4nmUla8YTGK0f6aOsYSL+O0aCwcklVTp3qsxeV\ns3JpMkgvrHWkj5cSkLU8eWK6DpFYnB/8/WECsSBVtvw3BHmmkCeFZFkLIYQYk3xzw8sa3Fm/Z57S\n1jFA84Jk1nIioRPRwrS8/h2Mh41UGetY4lzOwvkXYDdlF/2wmodClMk4tMRoLBXARnuOpun89uhu\nToVOsNi+nDfVrMz73ET6hkLmkIUQQswQuq5zKE+m8/CM43BGwZBgOHt+1qJamW9ZiK7DsfBhftfz\nK2770108evgJzlnixmxSqS7PrYGdmkvW9WTGdCBc/FrlfL36jkAnT596GrNi4a3ll+WUxEzpG0gu\n7yrlRmAspIcshBCiaK0dAyQSqUlV0uO5+WJZOBHCoBgwqWY0XUdVlPS88WXV7wWgP9ZHr9LG3z0v\nc6T/KCbVwIqm/EPHNrMRXyBGNJ7gZHcAVVU4b2lVUdftC+UG78dbf0VUi/D2yiuwG5wjPtdgUEgk\n9AkvBDKcBGQhhBBF8wWGAluly5LuPQ7vXdqtBp468Sv6431cUfsh+gYcVLttOfO/5aZKzq1ZyHuW\nX0IgFkBVRh64Tf2J6GCZzTHt/pSnd/uuxstpdi1nPitGfWqqcpg6yXsxy5C1EEKIohWbadyhvMbx\n8BGchjLsqjNdq9qfp6fqdpoxG0wjVsf6c8eLHOk/CkryNeJxjahW/DCyJ9yft0iJOV7OmprzCz5f\nkrqEEELMKJqupzuaFrOBcutQDzlTu/80jx1+AotqY0PVu7N6z/l6taP1PKOJKDsPPkZUSwZys2LB\netpKOB7mYws+z+GTXpYvzA7k3cFeauxVnA508svWp9jXc4Araq6lxjI/6zyPL5Kzo1Q+qSVTI80x\nTxQJyEIIIYqS6uUaDQpvbK6hu9tHfY0Dq2koqEUTMX706k+JaXHeWf0eHAYXMDRinK9O9WgVsAyK\ngetXfpSXu16h3dfFQCRAVI9QZa5D1/WchLFjAyf41xf/g/mOOjoCnejo1JrrMar5618XM+qt65O/\nBhkkIAshhChSqndb7rKkj9WW27LO2dP9Cu2B06xveAuL1Ob08VTcS+SJgKP1PA2qgRVVZ7Gi6ix6\nveGcHaYgWbkrtSxKVVQWuxtp9R6j0lrBpuYrSXhq03+jrtKGpkO3J4TFpGb12HVdJ6HpeWtUS0AW\nQggxI2iazsET/QA5BTwyXTDvzVgNFs6uXM7+1ozlUYNd5FRALnOYC25QMdxIQ9uvtnmoqbDRUO1g\noauBf1x9E13BbhwGFxajmX39felzq91WTEYD/b4IkZhGV38o/VinJ8Tp3iDzquxUu63E4loyM1zX\nmfwZZAnIQgghijAQjKa7uYWyjc+reUPOsVQ/NNUjbZrvIh7XxlR1a7RqYN2eEA3VQ9W8qq3V7D3S\nmzNHnOopp8pmZpYAPd0bTP+3byBMNJY8x2o2MMkJ1oBkWQshhChCZjwqNrmpImNo2+tP9oY1XQcl\nOW9sNhmwjGFt7/DgXVeZPVweigzNJ6cC7vCtHFO9+0LvIRWMk39Xn4oOsgRkIYQQhQUykqcCeZYu\n5dNQM9RjjcU1QpE4gVC85G0MM+d7a8qtOXO9Hb1BXj/RT0dvIG/tahgKxBVOS/4T8ogldJQpiMgS\nkIUQQozKH4rR5Rmaa62tGOqZvtp7gBO+9qJe5+Dx5Bz0mAp6ZMgcflYUhZpyG1XuoRKbA4EowXCc\nzr5QwfXJ9Rk3C4Vomj4lSV0SkIUQQoyqsy+Y9bvZmAwdPaFefvTqT/nOy/cRjueuRzaoCkbDxEWy\nzA0mUvPYC2udeYe99TwBedE819DzFYXKsuJ7yfmywyeaBGQhhBCjypxvXVxfhsloIBqP8oN9DxKK\nh3l/83uwGnODm6IoI9alHq/MJKtypznncf+w9cmNdc6sOW2AeZXZu0sBnLukErs1N9/ZYprcOtYg\nAVkIIUSRaitsuB1mdF3nv15o4bjvFG+Zfz4Xzl894nNUVZmUTRkybxKcttyiH/2+7B57ZVnu7lGG\nPL13o0FlSX0ZFS4L86qGAvbwAiSTQZY9CSGEGFVqznf+YID6zbHf8dzxF1lctogPnvW+gs+fjPnX\nzMQwl92Mw2YkEBoKmvkqgg1nUFXqq+1YTAZicQ3HYGA3GlQWzXMll3pNIQnIQgghcgTCMYLhODaL\nEX8ohqoO9Upr7TXUu+q4fuVHMamFw8jwJUY1efY6HqvhQd5iMmQF5Mw538y54+FqK3KHrVPslqH3\nZjJO/oCyBGQhhBBZEprGoRPerGOZy4jeVLuSS8+5kL7eIMWwmAxZQ74NNSPvPTxR0ns2U3oP3WhQ\nqa9x0N4doMyRO0890SQgCyGEyHK6L1TwHINa/LxwbYUNbyAy4trgieCwmvLuPAXjq+lR7bZiMaq4\n7JMfkCWpSwghRLY8S4YcttL7bzaLkfrq4tf9jv5ayRuB4fW0R+sFj2fBkqoouJ2WguVCJ0JRLXz1\n1VfjdCaHGBYsWMANN9zAbbfdhqqqNDc3s23bNgB27tzJjh07MJlM3HDDDWzYsGHSLlwIIcTkMGbM\nlyb0BF3Rdi5ZdN64XtPtMNOuBrPqTZeisc7FQCCKa9gQ8miFQPJlYc9EBQNyNJrMMvvJT36SPnbj\njTeydetW1qxZw7Zt29i1axerVq2ipaWFxx57jHA4zLXXXsu6deswmWZHQwghhEjq84YBiGoRnu75\nBR2REyxfUMFSc1PJr2kyGjhvadW4r81mMWKz5IauzHisKEO/n9VYnnc7xZmoYEA+cOAAwWCQ6667\njkQiwS233ML+/ftZs2YNAOvXr+e5555DVVVWr16N0WjE6XTS1NTEwYMHOffccyf9TQghhJg4kZhG\nRAvzq64d9MQ6Odt9Ngtc9dN9WaPKrMyV+tFkUvMG75mq4JVarVauu+46Nm3axNGjR7n++uuz3rjD\n4cDv9xMIBHC5hlLL7XY7Pp9vcq5aCCHEpIlrMX7d/XN6Yp2srn4zH1/5AVRlZvcy841YT0ZBkslU\nMCA3NTWxaNGi9M/l5eXs378//XggEKCsrAyn04nf7885XkhNzcjrw2azufq+Jpu0W+mk7Uoj7Zbr\nb39/mK5oOxc1ns9nLvw4qpo/GM+ktovoEIxnR+Vyl2VGXWMhBQPyI488wuuvv862bdvo7OzE7/ez\nbt06nn/Kk9TqAAAgAElEQVT+eS644AKeffZZ1q5dy8qVK9m+fTvRaJRIJEJrayvNzc0FL6C7e+71\nomtqXHPyfU02abfSSduVRtotv8WWs/DafFyz+L309gbynjPT2s7rDeH1hrCYDWiaTiyuEQ1HqRhH\ndvhkGO0GoeCVXnPNNXzpS19i8+bNqKrKN77xDcrLy7n99tuJxWIsXbqUjRs3oigKW7ZsYfPmzei6\nztatWzGbJ3/dlhBCiInVaG+izrQQk2H2JOVWl1mJxzWq3FbaewJ4/dGs3aFmA0XPt0fVFJpJd1gT\nZabdOc4W0m6lk7YrjbRbfgePe4jEtFGzomdy28UTGu09AeZXOaak5OVYjKuHLIQQ4swzGRtCTBWj\nQaWxbvbMHafMrFsHIYQQ0256x03PXBKQhRDiDPfnjhd5/MiThOPJgiA646v/LEojAVkIIc5gsUSM\nJ1qf4ncn/kQkkbH/r0TkKScBWQghzmB/bP8L/REvb1vwVtyWwdoRuo4iEXnKSUAWQogzVDge4TdH\nf4fVYOEdizakj8sU8vSQgCyEEGeoP5x8Dl/MzyULL8ZpGrYLk3SQp5wEZCGEOEN1hXpwmOxc0rg+\n67gkdU0PWYcshBBnqC3nfAB/NIDNaM1+QCLytJAeshBCnCGisQSalj1D7DQ78p4r8XjqSUAWQogz\ngD8UY/9RD8c6C5e71NFnd6muWUoCshBCzCGhSJzu/lDO8WA4BoDXH815LIekWU8LmUMWQog55ODx\nfgAcVhN269BXfGJwqDqcCBFPaBgNI/fHZAp5ekgPWQgh5qC20wNZv8cTOt6Yh592/Bcte/6HTk8w\n6/GEphFPaOnfZcR66klAFkKIOSgWSwZXjy+CxxchEkvw0sCfSOhx3MYKOnqGAnJC03jlSB/7WvvQ\nNJ1EQsasp4MMWQshxBxitxoJhuOYTMn+1rHTySQuT7yLI8HXqDbVsdh2FgCarqMqCh29Q8E5EksA\nEIokpvjKhfSQhRBiDjGoybFmXdfx+iPp43/1PAvAGvd6lMHxaM9A8vGe/nD6vGA4PlWXKoaRgCyE\nEHNIai9jXYe2jmTv+HTkJCfCrTTYGllgbUqf6w3kZlyf6PJPxWWKPGTIWggh5hB/KLm8KXMe2Glw\ns9yxkgvr1qDEhrK1NF1PL4cazu00T+6FihwSkIUQYo4IR/MPNzuNLt5W+S7OW1RFLKbRH4jQ5Qnh\nD8boVAfXLCtkrT+2WSQ8TDUZshZCiDmisy+3IEgmVVGwmA3UVdhRB+eaU4VCljW4s841jbJOWUwO\naXEhhJgjLGYDANXl1pzHjIbshcWpZVEpJoPK2YvK0787baZJuEIxGhmTEEKIOeL04PIlq9mA0agQ\nj+u4nWbMRpVqt23U56oqqOpQH81skv7aVJOALIQQc1DI1MFASKG5YjkOa25v12EzEggNzTmrqoIh\nIyArUqprysktkBBCzBEuezLwOuwqvzj2OE90/RTFkD/Rq7HOlfV7KhjbLAYcNumrTQcJyEIIMUcE\nBpcwPdf+F/ojXt62YB12U/6haovJwJKGspzjZzVW5CR4iakht0FCCDGLJDSNk10B6iptWM3ZX+EG\ng0o4HuI3x3+HzWjlHYs2jPpaZXYzyxa4UYcNT8tw9fSQHrIQQswi3f1hPL4IB471k9CyM6UTCZ3X\ngi8SiAW5rPFtOEz2gq/ntGVv0yimjwRkIYSYRTI7r5kbQOi6TjQR49WBv+M2u9iw4KJpuDoxHnJb\nJIQQs0hmwY7M/YuDkThGxcjVdR+nbr6O1WiZjssT4yA9ZCGEmEX0jPKWgYydmQYGN4qwGuwsdi+a\n6ssSE6CogNzb28uGDRtoa2vj+PHjbN68mY985CN89atfTZ+zc+dO3v/+9/OhD32I3//+95N1vUII\ncUbTMiJytyfEnkM9BMMxerzJLRTrKkcvACJmroIBOR6Ps23bNqzWZCm2u+++m61bt/Lggw+iaRq7\ndu2ip6eHlpYWduzYwf3338+3vvUtYrH8O4gIIYQoTb8/wqnuQNYxTdc4fGogvbuTxWSYjksTE6Bg\nQL7nnnu49tprqa2tRdd19u/fz5o1awBYv349u3fvZu/evaxevRqj0YjT6aSpqYmDBw9O+sULIcSZ\n5Ojg/sYAdquBPQN/4fHOFmKJoaHrzB60mF1GTep69NFHqaqqYt26dXz3u98FQMtIs3c4HPj9fgKB\nAC7XUNUXu92Oz+fLeb18ampchU+ahebq+5ps0m6lk7YrzWxqN3dXsnccTUT5s+9JXvDuwWl0odvC\nuC3VACxaUIE9T6nMyTCb2m42KBiQFUXhueee4+DBg9x66614PJ7044FAgLKyMpxOJ36/P+d4Mbq7\niwvcs0lNjWtOvq/JJu1WOmm70symdtM0Ha83RDAR4Knun9MT62S+ZSGXVl2FMWzHGw5RV2kj4AsT\n8IUn/XpmU9vNJKPdxIw6ZP3ggw/S0tJCS0sLZ599Nv/yL//CxRdfzAsvvADAs88+y+rVq1m5ciUv\nvfQS0WgUn89Ha2srzc3NE/suhBDiDNbeGyCUCPD/Oh+iJ9bJ2vlr+PybrsdmGCr+IfPHs9uY1yHf\neuut3HHHHcRiMZYuXcrGjRtRFIUtW7awefNmdF1n69atmM3mybheIYQ44+i6Tk9/GKtqp9G1kAXu\nN/OeJZcPlrj0Z5w3fdcoxk/R9en9J5yLQx4ylFMaabfSSduVZra0mzcQpa19AICzFrmxmYfmiPcc\n6kn/vLDWSZXbOiXXNFvabqYpechaCCHExNJ0nUg0UfjEDKlgrKpKVjAGqCwbqsilI13k2UwCshBC\nTKH2ngCvHfPQNzD2xCuDIXcXpgW1zqFfJB7PahKQhRBiCvX0JwNxqIheclewm2AslP49s451iqoo\nLK4vw2YxUO6S+tWzmWwuIYQQU8QfGqpg2O0J4XaYcdryrxmOa3Hu3/cg/miAq2o+jkW1Uj3C/LDb\nYcbtkETa2U56yEIIMUU6erPLXh4+6R3x3N8c+x2n/B0ssi/FoiYDcWXZ1CRsiekhAVlMKV3XicXH\nltAixFyhqrlzwPmc8nfw66PPUG5x8/a6ywCor7YXeJaY7SQgiyl1osvPq20eQpF44ZOFmGN0rfA5\nCS3Bg6/tJKEnuNB1GcFgMoi7nTI/PNdJQBZTqm8gAmTPpQlxpvCHYigKLK5PlhauyJOEdcBzmOO+\nUyx3nkujbWn6eJGdazGLSVKXmBayOkOcaTRdByX52beYkn2hfEPYb6g6i8+t+iSe7uxgnazKJeYy\nCchiWshXizjTRGMJ0JOFPJTB/wPyFUrUNJ0yfT6aJUIkVsQYt5gzJCCLaZG62e/0BDGq6pSV+xNi\nusQTyeBrMqqj3pEeOtlPKJKb+KhKD3nOk4AspoWCQiAco6MnCIDTZiKhyUC2mLti8WRv12RQ0/E4\n304CscQIvWKJx3OeJHWJaaEoEM0YjnvtmIfWU/3TeEVCTJ6EpnHsdHIjBqNRTY8Q6eiE4iFavcfS\n5zqs+QuFSA957pOALKbMQCCa/lnXk3NlmTyDGdhCzDWne4Ppn112UzpBS9N0fnrgEb790n9ysO8w\nuq7j9UdHehkxx0lAFlMn4wZfR6fLE8w5JaFJEouYewLhoXX3BjX5tavrOrt7nuVvXXtZ7F5EnbmB\nvUd6s55XWWbBbFIpk7KYZwSZQxZTJ6NDHItreTNI43Edg3z3iDlm+C5Nmp7gT57fcCDwdyqtFXxy\n5Ufp6Y2l55QrXBasFgOVLgsmo2EarlhMB+khiymjZWSwJBL5E7giUlZTzDH+UAxfILsQzoMH/jsZ\njE21vKf2WpSEJWuO2G41Uldhl2B8hpEespgymXPGI2VUh8JxyuzSRRZzR+YGEiuaKgDYsPAi+v0R\nLq64HJNuTi//SzHm2WZRzH0SkMWU6fEObcjuDUgCl5j7hu/uZDImA+0SdyOXVL0nfVzXIE5yCqe2\nwobbKTelZyK5DRNTJpiR2DJS7paWb2GmEJNE1/W81bImSmdfKP3z8oXlWeUva8qHiuEkNC05rK1A\nfbVDljidoSQgiykx0peecXiyixQHEVMkoWm8sL+TY52+SXt9AF88OWRtMWd/3TbUOFm+0A0wVJlL\nPv5nNAnIYkqM1PNdXF/GkoYyli1wD543lVclzmSpyln9vslZ9xuP67we2MfOju/jMR9OL3fKZB+h\nCIg4M0lAFlMiNUQ9fG7MYTVRZjdjHpxb6/WGiY9UOlCICVTsSHVHbyCrqE1xr63zm+O/5Q99v8Js\nMLPQXVfU82Tu+MwmSV1iSqSGog0Z283ZLENLOlLJLpAso7lySdXUXZw4IxVTOz0W1wbngUO47CYa\n65wFlyL5YwEePfQEfz39Ek5DGR9e+hGWlTcVdU2L6lxFnSfmJukhiymRWl+cGZAzE1wyfx5pjbIQ\nE8kfGlobnBq+Hu7IqaElS75gjNMZSVoj+fGrD/PX0y8x3z6fq+o+Qp29dtTz51fb0z/n2x9ZnDmk\nhyymxMBgfV5ZX3lm8gaiaJpOhcsy3ZeSdro3iNttA6C9J8DCWmdOQAxHswvVFJORfcWSd9JcvpSq\n6DkYFANKgSBbV2FH03T5f0NID1lMvnhCS69Bzpwjk7niM0db+0B6t6OZYHiSoccXoWcgPMLZ2XRd\np9V7jD+e+kvexxeVLaTJsAqDkhzarihiXnh+lYOacltRf1/MXdJDFpMuc5vFzCHraJ5a1gAWs5QL\nHAtd12fEzU08oRXs5WmDuxmd6vbTOM81LVXZYnGNA8c9Ocf1YXPKw5fgRbUIf+l+kR+17aUr2IOq\nqKyufSN2U24gTa25r5Ba1GIMJCCLSecLDmWoqqqCouTPcF3eWMELr4RkH/Yx0HWdvx/uxd0dpL7c\nOm03M8dO+/D4IjQvdOfs55s5zBuPD+0L3O0JlRyQNV0nGI7jtI1t2VAkmuC1Y7nBGLITC0OReHq4\n2mkz0eHr4Ymun+FPDGBUjSy1n8My+wpMau5XaOb7LZesaTEGEpDFpDvdN7TNoqoonLe0ihNdfirL\nrFnnlbssmEyqVOsag9dP9Kd/DoRjUx6QI9EEx7t8BELJHmG/L5ITkDOXDGX2TIfvgDQWh096CYbj\nLG0ow1VEUE+NIpzs8Wcdn1dlx+tNJmqlEgt1Xefg8aF2tZoNHIm/hD8xwAVVb2HTist5/WjyM62Q\n296p7G271YjbOXPmzMXMVzAga5rG7bffTltbG6qq8tWvfhWz2cxtt92Gqqo0Nzezbds2AHbu3MmO\nHTswmUzccMMNbNiwYbKvX8wC1W4r3f3J+bnUl17jCMs7VEUhMQOGX2eLeEZG+nRk6A7vbQ5fSqTp\nOm0dQ3PHmSVT+31RtFq9pOtODQnHi8zIP9I+gD8Yy7oJcNlN1Nc46ez20e+Lous6/lCM9p7s+tMu\nh5kPnf1enIl5LLOvSAdjgEAolhN0PT6p0y5KUzAgP/PMMyiKws9+9jOef/55vv3tb6PrOlu3bmXN\nmjVs27aNXbt2sWrVKlpaWnjssccIh8Nce+21rFu3DpNJKtGc6VLf0Zm1e0eiKhCTHnLRMmPZTGi2\n4QE5NkKeQMrB4x7Oaaos+e919gULZm4PBKP4g8klTqkldQ01ySQqo0GlzG6m3xeluz80VMIyg8tm\nQkdnmWNFzmNtHT5WNWf//VPdyYCeWbtdiGIUDMiXXXYZl1xyCQDt7e243W52797NmjVrAFi/fj3P\nPfccqqqyevVqjEYjTqeTpqYmDh48yLnnnju570DMeKnkmNqKwlmkBlVF0xLoup61NlnklxkAA+HY\ntC0rWjzfRdtpX9bw9IkuP70Z2fXewaVvZpOaTuiLFAjY+WTO0Q5flpRPKE9grHYP3RymPmf5gjEk\nRx5Kudmpq5SsaTE2RS17UlWV2267ja997WtcccUVWf9DOBwO/H4/gUAAl2toGNJut+PzzZxlDmL6\npIJGMUOTqRjsC8VGP1EwEIxmDdn29BdetqPr+qTM0budFtCTvfTU90OvN/t6UklTdRV2Fs0rvSLV\nia7seeCRinqkrqGjN5h1TFWHF6UZekzXdfb7X0ZXs0tlFntzGI7GsVuT/Zx5lfYCZwuRreikrm98\n4xv09vZyzTXXEIkMzZEEAgHKyspwOp34/f6c44XU1MzNUnFz9X2Voq0rgNtto662rOAXW12tC9UT\nwuWyUVPgCy0QivFqay81FTYW17sn8pJnPE3TaevqTBe2AHC7bQU/d/vbevEHY5y/om5CRiDKuwOo\nqkJNjQt3V3Ko9mh3EJfdnHVt5yyuxKAq9PSHaKhxYjCo9A8mglVWOQmGYyQSOuVF9PBTn6eUikoH\nNkvuV1kwHMs5F8BoVNPt1BPs43D4NU4kvEQTEQ77DtIePIGp3M/Vze/HaFCpHlwfvCym0e3JrdTl\ncFmxW02c7g3Q0R/BZDFR5bBQW1v4+2+2k++5iVUwID/++ON0dnbyyU9+EovFgqqqnHvuuTz//PNc\ncMEFPPvss6xdu5aVK1eyfft2otEokUiE1tZWmpubC15Ad/fc60XX1Ljm5Psqld8fJpHQ6RmW4Tpc\nTY2LRCSG1xui26yiJEYfjtxzqAcArzeE06TS6w1jMqqUOeb2UpNAOMahE0MlHZcvdNM5EMXrDbHv\nYCd1o9zInOoYAKCryzchSWD93hB2i5Hubl86WxnI+tlpMxHwhTCoKjaDQl/fYNJUIoHXH2XfwU66\nBgPdecuqCu8FPPi8lN4ef97s8tTnI5/U/59tkeP8aO9Psx47t+oc3ll/KQZNQ9e09LkWRcdlUXFY\nTRgNCq+2JRPa9h/qZtE8F4eOedJD6BaTOue/A+R7rjSj3cQUDMjvfOc7+dKXvsRHPvIR4vE4t99+\nO0uWLOH2228nFouxdOlSNm7ciKIobNmyhc2bN6eTvszmuf3FKAoLhuNjqk2dXnoyxn0Y9x7pSWfw\nvnFZ1Zyef84MxgtqHMkt/AaSAaqjN5gVkOMJDV8wRrnTnNUmmq6jTsSKb51RA+hZjeV5e68ADpsJ\nrz+aDsYAiYSGWqCQRqq4jMthwheIFTUEH9UiOMy2nOHtN88/l/cufg9er45BMdDoWsjqJY15X8Nk\nNFCd0dtumu/iaIcPXzBK30CYaMZrS01qUYqCAdlms/Fv//ZvOcdbWlpyjm3atIlNmzZNzJWJOcEb\nGNsSkNR3ezFfsiaTms7izVxOk9B0jONY4zqTZc7L2iyG9HDqkgY3Lw/2SjMT4rr7Q3T2hfC7rSys\ndaafOxHTyOl/o8Gmbl7ozrpZaKxzjhiMASzG3BSWV9s8nLe0atSAlvqzqRu9Pl+EhnxD1gk/R0OH\naAsepDPazicWfQbI7iQYDUYua7qIvx/uBcCkFF9N2GZO/s14Qud45+ijP0IUQwqDiEmV6s1UF7Hk\nCSAVJzr7Qsyvcox6rstmoi+WG/APnfRy1sLyOddL0XQ9K6GpeWF5+ufMIiu6PnRjk9rRKBiOEQzH\nMs6ZgIiciseDf8thNXFWY3m6qIYpT8DNNFIRk0A4NmKxj2giSne4i1Ohbhaa61Bx0e0J0VA99Fn5\nc/sL/OX0ixzub0sfa3QsJKIHsWDGYcv+2sscOShmJUCK0Tjy52uMAzxCABKQxSTSNJ32nmSG60jz\nugktwelgF+3+06j9Gv2eCMZYNW5T4bWpI+1nG4km8Idic24u+WRGMK4ss2QNFauqkl5alDkcnVpy\nFookeD2j9zox8Tj5IsoIQ9+pbON8NF3jVPAkL/T/jRPhVsJakLMdq3iz+61Z9c4BXu09wO9O/Il2\n/2m80YH08ctt76SRVTmvfdjbxpH+o8yzLGC562zeufwCKqzl6fKeo2Vlj2XZmEEd+Yajsc454mNC\njEQCspg0oejQ+s/U8F6mX7U9ze9PPkcglr0s5dKqq3CbKmnvCVCf0fOJafGs2sGpYLOg1sHJruzq\nSjNhs4WJlgqiVrMhq11S1IzSj5DsUY+0tnYilj7pw3rImdcAIweslzr38LODjxGKJ4fYDRhwmlyY\n1OQN1PArOzZwgtf6XqfCUs5ZFcuw6mWYdSdnV5xFcLBQWCgSTw+Pv7vpMq5cspGjJ6LYLEYqrMmR\nhFSPfHjAB1g0z0UgHBvzFoiZIwIpyxeWj3ozIsRI5FMjxiWe0AhG4nk3CUgViairtOUdvkzoGgbF\nwFvmn88CZz0N1dWcPO3BEpkHQJcnlBV47t1zP25LGVcvuwKXyYUvGENR8n/xx+IawXAcq9kw64eu\nNV0nHBm6uWma78obONLz74P3IqP1BGMJjfGWrcgXkPWccJqrwlqB1WBhde152KMN1FsaWVRXQSKh\n0dkXyum9r6tfy4YFF6V3VWptH2AgEGW+vYwjnmSPOTMgV9kq0XUdXe/NukGodlsJhGPU5tnmsMJl\nKamoyvA58oW1TgnGomTyyRHj8mpbH7qe7CkMJDw8dvgJTge68MeCoIMRCwv987ip6hM5z7180dv5\nX4vfgTqYSFNT4+Jwoier9nFKOB4hkojyYuceDve38YGFWwA7up4/o7WjN0hHb5Ayh5kl9bN7Peje\nwYSjlJF6cangkxrKzxeQXXYTvmCM1lMDrGquHueV5Q5ZK4rOQLyfhDHAnzuO8qaalViN2YFucVkj\nd731SyhKcl1yny9CjduazrYe3nt3W7KXiaRGAIZnjWdKtUFm7WqjQWXpJKxXP6uxnFAkjstukq0W\nxbhIQBYl03Q93ZsJRxNYzVZe6XkNl8lJhcVNJB4nFA8TSuQWUwAwG3J71YbMYJMRZ61GC19c8xme\nOvo7nmh7ih3HfsrVtR/DqJryDkGmZJZynI3yDb2P9H5TQSkSS2C1GIgMroktc5gZCESxWQw4bMmA\nPFbheJg93ftYXbcqPW2QOYX/0wM/Z3/v6/RHvFm95AbnPBpdC7JeKzOQVpfb0pniqcORaIKQIZ43\nQ9sfiuW9/tS1nOoJEArHmV+dXPo12mdjotgsxlGzyYUolnyKRMkOZWz9l9A0Kiwuvr7udtyWZI80\nNbR47pLiNw9w2kzpAFI9bHtGVVF51+JLCcQC/O7kn3jR+0fWVlyCNZWtq5A7ATnLDQ/ITptpxDXW\nqWmB1H7DKRUuC5VlFpy25M3L6cFSkrG4NmomtKZrHBs4wXPtz/NS5x6iWgyLwcKbalcC4B282fH4\nIpwOdKGjs8S9iEprJVXWciptFVRYykd8/RyD7yu1OYPFpOZsPHH45FBims0y1Bv1DISJxYcqaaXe\no2GMc8JCTCcJyKIkmq5lJQyleiipYAzJIA1j76XMr7IzEIgSCMfwh2I5m9BfuXQjL51+FV9igAW1\ndowGlbMay1EVBYNB4fBJb9amA7F4YtYOJUaHbb4w2hztSL00g0HJmuN3O0209bXzq7aXqLaXs67h\nwpznPNf+V55o/Q0D0WRwr7JWsnb+aprKFgLJYN4+GDjLHGa2Nn96bG8sj+GhMxLTiCe0EYfoDarK\nsgVuDp/0EookCEWGRmJSveip6CELMVEkIIsx29fzGo+8/j9cWnE1TmMyAA+vrBWLa+lN60utmhWK\nJDh80su5SyqzvpTNBjPvnfdhzNiodieHJjODUaXbmg4WkFyXvGIcW/xNp6OnB7J+H23D+3KnBcid\nfzcZVHpDHp49tZvjAyc5OnCSqJZcv72u/gLWkRuQlcGFUxfOW83qulWcU9mcnusHONk9tARropb4\n5Puc7Gvto77aTk25Le/jheKtxGMxm0hAFmPyuucI9+9rQdPBnxig0lZOdLAn09YxQG2FDVVRcpaC\njMXwUowDgWhW4QuAMouLxAhLm4Z/CQ/vZc4mNouRQChOZZmFyjIrjmEZvDEtzvGBk7zg6WZf+yH8\nfp2LKy/POsdoUOgO9LDr+B9QUKi0VFFhWMpC6xL+17IL8v7dtfNX89b68/M+Fo1l15Ie61KhkYyU\nDd/eE6R3IMI5iypyHit0s1ewLrYQM4gEZFG0V3sPcP8rD6LpOu+oupp5lgXYrUaisSjdg1v/eQNR\nGjNKNI5SO2FEw79DtXwFQHSdkUoxV7gsOeuSZ6tUQKmrsGdVtvKE+3nk8BPs7z1AJDEUHBc46yl3\nmZlXaafXG0YnWYN5gbOem9/0KRa4GrAYLOnM7e7eGI11uVXU1FFKSIZjQ9MBE7nEx5lRQauu0kZn\n39AQdCSayMqkbprvGrzOAgFZushiFpGALIryzPFnefTw/6CicknVlSy0LcZoVJhf6aDfl5HJrJNV\n13dZwxiSegYN7/WM1L8dqUKUQVVZ1Vw96m4/s0EklkjPhQ4v02gz2nilZz8VFjdvqDqb8xYsp5xq\nam3V6fZrqBm6MXKaHTSblw4932IgFEnQNxChsW5sW+h5BpLD3QaDwuL5E7f9nslooK7Shs1ixGo2\nZAVkSG63mfq75YND98Nv+BrrnFmfv7m8yYiYeyQgz1GarnOqO0BVmSW5G9A4hRIRnCYnl1S8l1rL\nfAAqXdYR6xGnWAs8ns/wjSF6+0M5xRx0yOohdwd7SegJ5jlq08dSu/G4nWY0Xedohw+71ThrNo7P\nXEc8vPiJ1Whh29ovUmEpR1GUMW+Fl5mQN1riVDSWIBrXshLrPL5kQK6rtE94slxm/fLlC930+6No\nmk6PN0zHYOZ0ZUYBj8yAu6ShLJ28lgrKpXz+hJgusiZgjgqG4/R6w7x+wpu1kYDXH+H1E/34gtF0\nFnQx3tV0KTe/8bPpYAxQM2z96HCrmqtLGjIc3quJxLScwg86Q/G4O9jLXX/9Jg8ffDTrvaYSvQyq\nQjiSYCAQTS+HmS3iWgybM573sUprxYT0AE90+XntmIdQJPfv7D/q4fBJL30DQ7tMuZ3JoFdZQmWr\nsbBbTdRXO9LD4sFw8voybx6y6nkP/pw5jC7rg8VsIgF5jsostZjZ0+oZCBMMxzlyaoBXjvSli0cU\noioqfl9G1SOjkl7D+obFlVhM2R+l5QsntiJSzjxyxhRyjb2KsyubOdTfyqu9BzKuefBUPTsreDbw\n+H49+BUAACAASURBVCIcON7DUz2P8OCRB9LLjyZKZs/R648SiSY4eLyfV9v68ta5zhwGTlXBmqr5\n2fJhmeWZ1bcy70dSS5xkmFrMVhKQ56iTGct+Mr9fU3vIpgTCxVdtCg9uFrGw1pmV8Wo0qCxvLMec\nEZQnYpgcsos/ZNLRs76N37v03Sgo/OLIr9D01A1I8vGBYDSr9zcRGytMtsPtvfy65xHaI8epsdVi\nN4638nQ2lz3/v08srhGJJujqD9HpGRpNyAyCmqajKFOXwayqSlavN3P4PjP4SgKXmO0kIM8xoUic\nhKZhygiOre3JYWtN19PDfinDexNxLc4vW5+iO5hdPxnAMHhulduaM6dpUNV0cf5SivQP11DjoL7G\ngXVwl6ic/XuHJVnXO+dx4fzVdAQ6ebFzDzAUrxMJPeumpGOGD1sPBCM80/tLOiLHabI184ElmzCq\nEzv06hxhv2FI9oDbuwN09Ay1UyKhZ+ytHJ/yghuZn9vhOQbDj1tMyeSwZQsmvm61EJNJAvIcEk9o\nHDzez4Fj/VkBLBLTeLWtL2vtaOZzUjoDXXzrpXv59dHf8vND/w+vP5LuJWm6TiSWHeiHq6u001jn\nZOEEFIqoKbdRW24b2sEoNx7nzF2/u+kyDIqBp44+g67rI/bgUuUVZ6pfHHmC4+EjNFiauLTqSizG\nid/X2e0wc/ai/Bnw4Wj+OesuT4hYPDnFMZ1jDMMT0BbNc9FQ48i6SZxf5cip8CbETCcZD3NIKvs1\n3y4/8YROvz+Sc9wfiuGym3ih+0UePfRLolqMtfPWsGn5lRxoS85bxuMaLkcyKIw2TKkqSk4Bj/FK\n9eAzbzB8wWhy6H3Yp7fKVsmWcz7AEnfT4PPyhw2HbeZ+7HVdx6iaqDBVc03TJlTdPOLw8nhZ8+xR\nDaQrrKU4bMniJDaLgdb2ZOUw8yg1sCfDkoYyWk8l//bw3vlEjMgIMRPM3G+mWcwfjBKOxkf8wpss\nw3vATpuJyjJLOiEnlehVX+Ogpz9ENKbh9Uf577aHORY+jN1oY8uKD7LYdlY6GAN094fThT+m+ssv\n1Vs71R1gaYObSCzBkcEv5nzJO+fPe1P655GSe4YHnJkiEkugaTqrXRfTbFzDwuqKackSTt3YQXKu\nub7awcHj/SQ0Pb1cKnON81TIrMU9UZXBhJhpJCBPME3T2d/Wh9cb4g2LK0fdTWeilTnN6Xk+gHKn\nOd1jPd7pJzJYQtJuMXJWYzmvHOkDYIF1MSgK179pE26LO2f/3UwVo9RSngyp4JkqkOEvYevAFJfD\nhC+QfP5M3HDitaOe9M8m1VxwjfdEsJiT2zRWl1tRFYUeb4jM1XA1Fbb03GxP/9DSp+kYDm6scxKL\na5K8JeYsCcgTzJux/27vQHhKi1AYMnqE86vt6X1mh+8fa1CVrKHnc5yrWOF6E+UWN38fJRgrClMS\nJDKZTWq6FnVC0zjRNbT8JifRK4/6ajvtg8lJmUu8jp32z6ikn+Od2cuaHDbjlGQxNy9wo2k6ZlPy\n3zUYiWfd9CR30JoZPdKJng4RYqaZGf+nzSHR+NCX/lTfx6eWMDXWOamrGLoRmFeV/DmcCKLrOiaj\niqIoVJYle7upod3U/GDK/Co75zQNLW9yjZKZO1mW1Cd3kzIZ1aweJGRXmxpJTbmNc5oqsJgNNNa5\nWDz4emNZ7jVZNF1j5+uP09p7mr6B7Pn9vPW7J4HRoKaDMeTOzxoNSs6NwUy6kRFiLpGAPMHiGet8\np3q9a+rLdPgwucmocCi0lx0d3+c0B9NzcPXVjqy1w5k96QW1Duoq7VhMBpoXujGbVOqrp77kpNVs\nxGI2oOt6VtsWoyvYw7+/fB8nAsc5Z1EFTpsJt8MMSrKCU3yE3aKmypNHf8sfTj7H44d+nfPYWOtL\nT5TM4FtXacubByHZy0JMDgnIEyxzS8Ap6uSkpeJ/ZtLL8YGTbP/bd/l9z69RlOz9dI0GlRVNlTlZ\nx/Oq7FS7hwpROKwmVjRVTnmSWkokmhhzMAYIxAIc6m/loQP/TTg+NP9pUBWC4Tj7Wvto75maXaF0\nXSccjaeH2Q/3t/Fk2y5cxjLeUn5p1rnzq+zTVvIxszOcWVdaCDH5ZA55gsUSGupgD7XbE6KuwjZq\nVmhwcOh0IipbpXrkqqKQ0BI8dODnPH/6b+jorKpZyablV1JuyR1utJmNWZnHI+0zPNPUVIxevWqx\nexFvX3gRz5z4I9/b+2NufOMnMBtMyfYZXBLV5QlRXz35gafbG6a9O0B9jQOnAx549WcAbKi8Aqth\n6H001DjSNcKnw0gFP85bVoVnIDKh2y0KIbLJ/10TTB8Wyzy+yIhfsLqu8/oJL5DciGHcf3uwE6mq\nYFANnPJ3UO+cx/uXvYezKpeN+Dy300yPd6gHWVsxs3ZDctpMWdnjUHx7vXfpu+kLe9jTvY9/ffE7\nfOLcD6Mq2Tc/CU3LqTw20QYGl6T1+yI81fEbPJF+3lz2VuZZFgDJ4eFgJE7VNCcumUz5k/ZURaHK\nLUlVQkwmCcjjlJqHjMWTVbIA3BlDu6e6AyMG5HwFPMbKHwugomBWrUQGN45PJWldv3ILldaKUTeb\nB3DYTNRV/v/t3XlgFOX9P/D3zOzsfSSbbBJCyEEIdwAb8AKRHrZ41VK1CAWP2oNv6wVotR6AFcWK\nRytif3y/alVqK1RBbW2tYBUUKCKHKAgGkkBOcm/2yh4zz++PTWZ3yX3tLtnP6y+e3dndmYfNfua5\nPo8OJr0aGpGP6lKt3tCqhYiAPNLW+xatwAu4edJCvPH12/ikai+ONRYjRz0FXn9oNrzHK8GoG9pr\nbl+qE5BkZBoykGvKwXnmi5Tn0636qOWG7o6xrQVsNkR/Ah8hiY4C8gC1B+H+BFcpbJBZllmn6ys9\n3gC8fqnDjjcOnxMflX+CDys+wazMCzFBvFhZZ9z+w56qS+nVefAcF9fjhWfvadvXLl2RV2HB+Gsx\nPf08jEnKQ2l15BIjn18ChniiUvuNm88vozB1OsZpz0O9PTizOivNEBfBGAgOnUzJT+lyS01CyNCh\ngDwAXp80oFZu+Cxsf0DusMbX7vQqwSMnI5glq8Z1Bu+VfYiDtZ8jwCSYRCNSdSnwekLnMdwSJxjC\nguVAxjALkkd3+ng0JsOHL4erqo/c3OLsm61YG27fH0LOFd3+ugUCAdx///2orKyE3+/HkiVLMGbM\nGNx3333geR4FBQVYuXIlAGDz5s3YtGkTRFHEkiVLMGfOnGicf0y1dxH3RO5kowOvT0Jx2/gxADQ6\nWju0UsPHdT3eADRaGY9++gxkJiNdn4ZLsy7GBFMhNCoNSj2Ra4iHk/AEIElDkLpzb+1eeOucuCx7\nDozqwe8pCEgyAoHOo35epplSQRJCAPQQkN955x0kJyfjiSeeQEtLC6655hqMHz8ey5Ytw/Tp07Fy\n5Ups374d06ZNw8aNG7F161a0trZiwYIFmDlzJkRxeK9XPHsdq04jwOOVYNKrYbeHdhRijHXYmuir\nU5FJLpqdPqQn68HzHCqd1UjX2yJa0DzPQS/qMCdrJsYkjcaU1Inw+iUcO9UMIJRUIjyRx3ARnikq\nbRBmIFsMarS0ZVRjjGFv7T7U+2rx3+rP8PPCm5CflDvgz2jX6gvA19aLIqr4Dj0qYhdbCRJCEk+3\nAfnyyy/H3LlzAQCSJEEQBBw9ehTTp08HAMyePRu7du0Cz/MoKiqCSqWC0WhEbm4ujh8/jsmTJw/9\nFcTQ2XsLW4wajM7UID3dgorqUOtXloGeGkF2jxNbvzqAYveXKHdU4tZJi8F7RijP1zS4kWHV49qC\nq5XHKuoi19CmW3XQdDFL9lymEQWMHmmGbpDSdqZYtNBpBNTbW9HY4sXVaYvQpDmGd0rew7MHN2DR\nhB9FbFLRX7VNblTUObGtYSvG6Cfim3kzlI0+2sVqvTEhJP50GyZ0Oh30ej2cTifuvPNOLF26NKL7\n0GAwwOl0wuVywWQKZRbS6/VwOBydveWwEt6lDARbb6JK6LCWs7ucy27JhZ2N7+G1qvX4z5l/o9JZ\njcLUiWho6PiaszN/nb3RgmEYZ1Ay69WDuhmEXisqk8VUnAqX5czBL6f+BCpexMtH/4qPKnYN+DOq\n6t041PJfnPacxClPMUQVj7wRpogx2q52pCKEJJ4eb8+rq6tx2223YdGiRbjyyiuxdu1a5TmXywWz\n2Qyj0Qin09nh8d6w2WKTInCgSqvssLRlsyoYlQSTQR0xFpiZYYarbamONcUY0RJqbGlVXtvsO4nj\nVYdhVadgirUICy/4NgRZi69Kgzsx5Ywwo7reCZ9fhiVJH5EtK8cTQHPbVnlmgxp5o5LP+Qk50fw+\n+MHB5WfK59psRRidkYnn9r6MmWPOg83Uv3ORJBl2lw+l0hHsb/kEJpUZl+d8HyMyLNBpVMgZZcXB\n47XK5w6Wc/VvKdao3vqP6m5wdRuQ6+vrceutt2LFihW48MILAQATJkzAvn37MGPGDOzcuRMXXngh\nCgsL8cwzz8Dn88Hr9aKkpAQFBQW9OoG6unOvJe0PSDgRttFBIM2AJm+otWqzmZBqFOHz+FBvb0Vt\nbQsaHV7wHIfMVAMOFdcDCI45X5I1HQ2NXuRpx0MjquBuYjhSWhn6sFQ9vB4/Wlw+fPxZOSblWeEP\nSNBrRTQ2ueBw+ZGTYUKyQURDQ2R36LnGZjNF9fvQ0OhWxvrbP1cDI5ZN+xW4Vg51rf07lxMVduyu\n3Y29zR9Cy+txWcoP4XUC9mYXnG0JSAxqHnqNatCuN9p1N1xQvfUf1V3/dHcT021A3rBhA1paWvD8\n889j/fr14DgODzzwAFavXg2/34/8/HzMnTsXHMdh8eLFWLhwIRhjWLZsGdTq4ZtYwBU2dpyV1vms\n3OC2dcHWaqPDi1P1dVDzmog0jWaDGgIv4PsTZ+FIaSNEFY8jZY0R78NxkekMj7S1nDNT9crevslD\nMPM4EYQPJQQkWenh6KobWWZyj0lWAKDW2YQD9l0wCEZcYZuPJDEFY7IsEdnABmNyGiFkeOFYbzaV\nHULn4h1WdYMLZxqDLavCfGuHtIvtd46nzzhQXF+OLxyf4aT7KC5ImoP5Uy5DabUD7taAkv6RMdbp\nPsRJJjVyM8zwB2QlEHdmMNJuxoNo33GfaXKjOmxNcO4IU5drghlj2PDFy0jSJKEwdSIMzIpknRkW\nQ8fjDxXX44y3EjrBgGk52RAFfsgnb1FrpX+o3vqP6q5/+t1CJp0LX7rSWYYlxhgO1X6BD8o/RklL\nGQAgSWWFXjCiuiG4J3H4y7pqkeVmhPYCzk43dpihCwAakdaw9leqRRsRkMuqHZhW0HlAdgXcOOOu\nwxf1X+Hjyj0AAJFTY6x1NH459SfKcQ1tE/3SNSMxdpRlUDYNIYQkBgrI/dCe8nJSnrXTYHq0rhj/\n9+VGAMBIbS4mGb+BbG0+OI6D1y/BF5Ch6iFf9PicpIiyupPlTCNtBuquHgCB55Fu1Sm9HQBQVe9C\nRkrHvNJG0YD7z1+GrxqOo7S5Al/Xl8Pub0SZ/bRyDGMM5bWhmyYKxoSQvqCA3A9yW0Duaqu6ibYC\nXJX3PUy1TUZtdWQglWUGSWJQnxWQJ+Qm46uyJljNGtiSOm4MH368SS8iO90Ud5tAnIvODry1TR4I\nPId0a8cdr0RehSm2SRhtHIscBNeZTxljVZ73+UM9J7QzEiGkrygg94PD7Qe4rnP+chyHy/OCm87X\noj7iufbW9dkta40odDsWrBYFTMhJhiBwlGpxEHGd/B86PX6kd/Oa8E1B7E6/0ksRnq+6LztSEUII\n0ENiENKRxxucYS3LEv5Vuh3vlm7r0+vbW1GGfmySoFELFIwHWWf3VL4ecpRLYSlTqxqC2dIYYzhZ\nFconHi+7NxFCzh30695HjS2t8Ms+/LPub/hH6fv47MxByKzrHZ/SrZ0vbznXE3gMF50FTqmbhQcB\nSY6YXOdvu8FqbPECbS/LH9m7pDiEEBKOuqz7qNnjxnv1b6DGW4EpqZOweMKPul2b2t41LQgcJCn0\nQ9/q691OUWRodXZjpFN3/WfRcFa6VAA4fcYBpyeUGEY9iCk+CSGJg1rIfdAa8OLtyk2o8VagMGUy\nfjp5EfRi9wkeLAY1eJ5D5llbK9KmAvGhsxZyd3sudzaRr7HFG7GXtUhL0Qgh/UC/HH3g8DnR7GvC\naN043DJxAQS+55aQTqNC4WgrUixa2JJCM2/TkilTUzzorIXsOGvTDgCorHMqKU+DrzvrNW1Z0wpG\nWWj8mBDSL9RM6wObPgULcm4G82khqnpfde3d1iNtRmSmGmiHnzgXPqmr1RecxFfXHOyqbmkL1lk2\nI+wuH+xOX8Rru1oKRwghPaGA3EuMMTAAJpUFTr+/360gCsbxxaBVId2qQ5JRA4fHj6o6F8KndB07\n1RxxfIsrGIAFIZg97ainKWJuwNnrxwkhpLfo16ONLDNIMus02Ya71Y+vy4OJIHQaARRThw+O4zCi\nbXxfp1Gh2eFVlrZ1l+bdpBfBcxysZi3qmjxtr6fJXISQ/qOA3OZklR0uT0DZLOLTmgOo8zRgRvIs\nVNW5lOM8XgmggDxsef0SGAsmB5G7CMhqkVd6SMK7qPNHWqJyjoSQ4SnhA7LT44deq4LLE2wVeX0S\nPqz+AP8s3QadSotkbwH0gjHyRTHdH4sMpfbu55Iqe5fDC+HDFe2taQCUtIUQMiAJHZCdHj9OVNiV\nrkbGGF47uhWHmj9DijYZS6bcgtrqhK6ihCXLQFd3XgE5lAjGatJ0mNhFCCH9kbC39F6/hMaW4MxZ\njzc4q/YLx75gMFbbcPf022AWUpTjczJMUAmhJB8kcQUCoUBtNqhjeCaEkOEkIZt/lXVO1DW3RkzO\n8ss+HHEehF4w4rsp1wEBDcprg5tvZ6TokWzSQOA5VNa7MCrN2MU7k+HIoFOBMcCWpMOpmsgN2WnW\nPCFksCRcQJYZU9aUhs/ZMWq0+GHmIrh8bhhVJpRUhjYKsLS1gswGNbWIhrm8ESaUVkcG3YKs4N7U\n4ekxw5kN6ohMXYQQ0h8JF5DD14wCgFEnYkxWcHasx2vGqRpHRJ5prVqgNJcJxGLUQCU4EZA6jh+3\nz6g+u1E8OpM2kyCEDFzCjSHLcuQPbfiPq06jwvicZGWsGADG5yRH69RIvOiiF1qnUSEnw0TfCULI\nkEi4gNy+ubwgBDcB6Gw8uH09aVdbJ5JhrptlbckmDTQidU8TQgZfwgVkh9sHxhj2tLyPY/5dUKk6\n2X5Po0JhvhUZVn0MzpDEWnhCkBEp9B0ghERHwg2OVje48bnjU3xuP4RsfxYCcgBqoeNELeHs7XxI\nwghbZgxbEvWSEEKiI+GiTqn7a+yz70CSxoIlU27uNBiTxGbSiwCC3dOdbc9ICCFDIaFayCeaS/Fh\n4z8gciKWTLkFFg3NjiUd5Y+0wN3qh5Zm1xNCoihhWsiMMWw98S5kJuPKkT/EKFNmrE+JxDG9Vuz3\nFpuEENIfCdME4DgOC0YvxIGKYoyzjI316RBCCCEREqaFDAAOB4dsXT4sRk2sT4UQQgiJkBAtZMYY\nPj/RoJRNOjGGZ0MIIYR0NCxbyD7Jh22nPoLMgutXjp5qUp4z6UWaOUsIISTuDLsWstvvxh8Pv4wS\nexk0ghoXj7gQfn8wMCeZ1MjNoJnVhBBC4k+vWsiff/45Fi9eDAA4ffo0Fi5ciEWLFuHhhx9Wjtm8\neTOuvfZa3HDDDfjoo4+G5GQ70+oLwOEObhDf7LXjmQP/DyX2MhSlTcXFmefD4w0ox9K2iYQQQuJV\njy3kF154AW+//TYMBgMAYM2aNVi2bBmmT5+OlStXYvv27Zg2bRo2btyIrVu3orW1FQsWLMDMmTMh\nikM7VivLDMdONQMA0kZI+OPhl9DY2oRLs2biuoKrwXM8ApIXADAiVU/ZtwghhMStHiNUTk4O1q9f\nr5SPHDmC6dOnAwBmz56N3bt34/DhwygqKoJKpYLRaERubi6OHz8+JCfMGENJVQu+KGnA4ZOhiVpb\nvv4nGlubcPXo7+H6gu+D54KX5peC3dVa2hCAEEJIHOuxhXzZZZehsrJSKbOwxPsGgwFOpxMulwsm\nk0l5XK/Xw+GI3OS9KzabqdPHG+weyDJgS47MJVzb5AanEmA0RgbYbxuvxvikyVgw41vKYwFJRoPL\nD4tFh4x0M4z66KXJ7Oq6SPeo3vqP6q5/qN76j+pucPV5Uhcf1u3rcrlgNpthNBrhdDo7PN4bdXUd\nA7fHG8Dx08Gu6MJ8a0RX8+fF9V2+VyrycKK0HmaDGhzH4dCJemUrPXuzGx6Xt1fnNFA2m6nT6yLd\no3rrP6q7/qF66z+qu/7p7iamz4OqEydOxL59+wAAO3fuRFFREQoLC7F//374fD44HA6UlJSgoKCg\n3ydcVhP6T66ud0Nu28O4pW3yVndKqx040+SB1y9F7GurUtH4MSGEkPjV5xbyvffei4ceegh+vx/5\n+fmYO3cuOI7D4sWLsXDhQjDGsGzZMqjV/e8e9vok5d/19lbU21sjnhdVPLJsBpRWBwO31ayBy+OH\nt215U02DGzUNbuV4jVqgvMSEEELiGsfCB4VjoLMuj6NljfD55U6ODmrvxj7U1n09ebQVKoFHQJLx\nZUljxLHZ6UaYDWqohOi1kKkrp3+o3vqP6q5/qN76j+quf7rrso7LxCABqft7hPYx5dGZZrha/Uqw\nVQk81CIPn1+GWuSRnW6CkdJkEkIIOQfEZUAWBQ5eufOgPCbLovzbbFDDbIjsGp+Ya4UsM0qPSQgh\n5JwSlwFZZoBG5JFu1eP0meDs7Ul5Voi9nJhFwZgQQsi5Ji4DsiQzqEQeVrMWVrM21qdDCCEkwUgO\nB1xfHob5oplR+8y4WwsUkGTIMlOWOhFCCCHRJntb0fDu3+E8/HnUPjPuWsjltcEuam83s6wJIYSQ\noSSm2pD9wErwGk3UPjOuWsj1zR7YnT0n/yCEEEKGguz3gUnBXBiCTgcuipsSxVVArqhzKf8On01N\nCCEkevxNTbE+hZhx7N2LshX3w1teHvXPjpuA3NgSysY1OtNM64cJISQKAs1NqHjqCUht+xG0lpag\nfM0jYIFAD68cnswzZyF98c1QpaRE/bPjJiDbXcGu6tQkbYe1xYQQQoaGYEmCJicX7q+DW+YySULa\ngh+DUwWnGAWam5RgnQg4joN+/AQIen3UPzsuArLd6VXGjpNN0RtAJ4SQRCX7gr+5HMfBdt2PYPpG\nEQBAN6YAxvOC/2aMofqF/4Wn5ITyOs/JE5Dcro5veI6TvV7YP9kZ056BuAjItc0e5d9atdDNkYQQ\nQgaKyTJOr34Y7q+Odn9cIADDpELoRo9RHqt5YQMCTc1KuWn7+wjY7UN2rtEiuZxw7N2Lpm3vx+wc\nYrrs6dMjNeBkCS5PAILAoXB09PvsyfDhrawAp1ZDbUuL9akQEpcYY+A4DhzPw3b9fEiu7lu6vCjC\nevkVodfLMpK+fRnUI0Yo79fw9laYL7x4SM87GkRrCrKW3wMmx27JbcxbyM2OYLdJkpG6qsnA2D/5\nGM4D+5Vy+9KFzsh+X4fWgdza2sXRhJz7PCUlqHzmSSXgGAqnwDR9Rp/eg+N5JH/nu6GlQIxh5NK7\nIRiNAADJ7YLvTM2gnne0RXOZ09liHpDbWc0UkEnfeIqLceq3K5Wy6RtF0I0pUMpV659F6+lTSvnM\nq3+C3No2PCJJqPzD08p4kdzaitL7fw3JQdvJkeGlfYddbW4ueK0W/ob6QXtvjuehG50f/BxZRtXz\nz6H5Px8M2vtHA5NllD/5OzR/9J9Yn0psA/K4nGSY9CLyRphg0NIyJ9Kz8O27Nbk5UCUlKWVdwVjo\n8oNjXbLXC8nlgjo9Q3neefAgZK8XAMBrdbAtWKS0ov2NjbDMmg3B1PVepYPJeeggvOWnlXKMtyUn\nw1Tdpr/CsXcPgGDwzPzl7UM2pMPxPFK+/wPY5i8YkvcfKhzPw3bt9UAMW8btYnoGFqMG+SMtsMRR\nd7XkdMJ5cH+33Z0kRHI40PLpf7t8nskyJI+ny+f7qm7TX5WuZl5UY+QdSzs9jtdokP2bByPS3uWs\negSCyayUky6dozyvycxE6g+vU55r/s92eE6GZpYOhvCg69j3aUTigTN/egEtbT+cJLFVv7AB3orQ\nd0NyuXp9w9ayZxfqt7yhlHUTJqL11KluXjG49GPHKV2+vjM1kP3+qH12XzFJUoaptHmjkTR7TmxP\nCHHUZR1L4WvsAi0tqN3014i7pVgO8sc72e9D3ebXlXLA0YLS++5Ryt6KcpQ/9kjo+ZYWlD+xRimz\nQAC+mtCYk+zzRWQJ8lZVRnQl6Ubnw7Fvb7/OVWWx9Gp8KNDcjMb3/gWVdfAmGdp37kDDW1uUcsrV\n10A3brxSZoxBm5unlD3FX9NNYYJwHtyP1tISpeyrqgInhnIxnH7st/BVVSnlpvffUyZjsUAATdtD\ns4I1OXkRwdw4ZSrSYtBibS0rQ/njj8JbVhr1z+4t1xeHUfXH5+Lq7yzhAzILBHDqtyvgrawAAKiS\nk5G++GZwXHBPZfdXR1H13B9ieYpxhckyGv7+tvKDIFpTkLZgkfK87HZDExZYRGsKdGPHKuVAQz04\ndejHxltRgZoX/1cpt5aVouaFDUpZcjrR8t9Qy9E443yk33jL4F7UWVRJSchdvQZicjIA9HtdYvs6\nTwDQjR0b0UWtzsiAGJYJaMStP1e6171VVahav67HGbDk3OQ4sB/N/9mulCW3B/VhN2s5Kx6GOj0d\nQPDvTZuTC3VG8LvBGAse235jKQio3/KGMjdCk5mJzF/dEaUr6Zo6MxMj71gKXcHYng+OEsntRu1f\nX1N6G/QTJkI9YgSYP372TxBWrVq1KpYn4HZHvzICdjsktwuCTg+O58HrdOB1OohWK3hRhDotNMbS\nsncPDIVToc5om+YfCPTYyjIYNDG5rmhxHjwA95EvYJw6DUDwR6CdYDRGzNzk1WrlOCB4wxO+bmmf\n9QAAERBJREFUREJyOMDrdNCNzg/Wm6sVkssF/fgJbe9ngn7CBGUWZ/uN0lDjhOB6eBYIoPLZZ8Ab\njBHj0T0J2JtRtvIBmGZcAEGng2A0wXzBRb18NYOuYCy0WaMAAN7y03B89qkyeaYzw/07N1RiUW+s\ntRWN7/0TlksuBQCIVitMRdPBqztmKOQ4DqaiGRGzmvXjxivfRY7joBudD1VqqvKdjdYs4e7qjhME\nqNpuaIHQcqtY4gQB9W9sCtZXUjI4lQqGyVPAqaI7f8lg6HqIlmMxnk1SVxf9Wa31b22Br7oKmf9z\nW59ex2QZpx/9LdJvugXa7Jwuj7PZTDG5rqHEAgEllR5jDMznG/RtyeKx3gJ2Oxre3oq0RTf2+YfO\nvnMHxIwM6MeOG9A5nHn1ZYg2G6yXXwkgOEzAi5E/3vFYd+eCaNSb7PWi5k8vIOOWnyp/M7LXG9Vt\n/YZCb+pOcrtQ/8bfoEpJQcqVV0fpzLoWsDdDMFtienNgs3U9cXTYdFmzQKDbsYDwceCUq74P47Tz\n+jyzNWC3Q52eDs2obOUzHQf2D/sZsowxlD/5O7iPHwMQvCs/139MektlsSD9xpuVYNz84Qddblju\nq6lG/VtvKmXL7EsHHIwBwPajG5D0zW8r5eo/rofz4P5uXjF0/I0NEV3p3vLT8Dc2KmXJ40nYTQm6\nwms04EQRzgOfRTyWCDiehyo5WekN6IvBmLvDGEPNSy8o81RUlqSYt9S7M2wCsuuLz1H1x+eUsr++\nLmKWbNX6Z+E5UQwA4FQqmC+a2ef/GDE5GSN+/j/K65wHD6B527+VcqC5Gb662oFeStzhOA7WuVfA\n1zbOnsgcn+6N6Fps+Mc7CDhaAACqZCtadu8a1HWeAMBrteC1WgBtPRVqNfQTJyvP1299E1Lbcq7B\n5jl5Av66uojPch46oJSbtr0P99Ejoef/tgn2j3eGym9tQcvuXUNybvEmPIA49n8WMdkx4+ZbYb5o\nZixOK6Z4rQ4pV18DldkMxhiad3zU5czrxn/9M2KCZ82L/xcxYa0/OI6DbkwBmrb9e0DvEy3DJiCD\n46GfOEkpOg9/jpY9u5Wy+YKLeszb2lea7BzYbliolFv27ELzB9uUsqekBK4vDg/qZwJtXcZRbpUb\np52HpG99J6qfGY9GLrtbmajCGEPzhx8g0BBsIfIaDXJ/+xjElNQh+3xOpULmkl8pLazW06fQsmeX\ncpMgeTxo3vFhr9+vfuubqN8aatU37/gI9W9vVcrOgwdg3/2JUjYUToE6LV0pm84/H9qcXKUspqVB\nk52tlP11dRDTQ8fXv70V3srKXp/fQATszWgtK1PKA/2bCe8Z8Dc1RdSbp7gYVet+r5TF1FT4aqqV\ncvv4biLzFH+Npm3vKXXhrayEp7g4dACT0fjvfypFXq+Hafr5Stm+6+OImx7Xl4eVMmMM/vrQjWPw\n7YLPWWZfirQfLx706xkKwyYgG6edh+SwgKEvGAfzRaHJQ6bzL0DK1dcM6meq09Mjfow0o0ZFfoF2\nfhjxR9lf/sbGiLWFkr0Zpb9erpSZLEesaQ04WuD68osu369l7x7Uvv5az59bV4fa1/8yLHd26S9e\nVIcmz3Acch95DOqwSW3tLdlo0YzKxqh7fqP00rSeLIZjb2hduPPwIVSGrRJwf3U0ouWmKxgLXqcL\nvSGHiB4Ay8xZMBROUcrm8y+MmDlrmDwFmlGjlLJ17hVKchYAyLjl1oiy/eMd4DWh97fv+rjXKUsD\njha4j32llP1NTWj4xztK2Vdbi+adHyllz4li1G8N/d24j3yJ8rWP9+qzzuYpKcHpxx4JBQCfF479\n+5TnxbS0iGChzcntco18otJkjgz2MLavU66siAjASd/5LtJu+LFSTv/xYiXxj7+xEWdefRlo+54z\nWUblH54JvbkkofSB+5Qik2WcefVlZfgklukw++LcOMt+0IwaFfFDEA2GyVMiUjcmf/dymGfNVsrV\nG56Hp6Sks5dGkFwulD+xRrmjFwwGNH2wHZLbDSD4ZdONCV2bt6IcZza+rJT9tbVoCGvluI99hfIn\nf6eUVWYLWCA03t56qqzT3gNepwPz+eD+8ssezzlRCXpDp7Njo4XjOIg2m1LWZOdG9NoIOr2yhAYI\ntiTCh1UMkwthnRvaPCBp9hxl8hgAqEdkdju7u8fzU0XuX5O7ajVUbT0I3qpK1G1+HZwYnOXqb2xE\n2UP3K8dKDgcqnnkyVG5uxpk/v6KUA40NcH1+SCnLbhfsH4V6B3Rjx8ES9vfHqVTQT5iolN3HvkLl\n22EBva424ubTcWC/ktlNm5cH45SpkNv+BsWUVGTdGbopVlksyFp6d6/qJFEJRmPEZFjduHER3z1e\nre5ybF0wGJC19O7QMCNjSL3uR6FAKwgwX3ChcrzsdsNXXYWWvV0nLYpHCbnsaai1LwdQmUzg235s\nJIcDTf/5ANYrrgInCGCMBZf8tH0BfWdqwGk04AQBvFqN5g+2Qz9pEgSDAZxKBcusS6BqS+so6PQR\nS4ukFgd4nVb54eQEAWJaurJ2UXK7ITU1wlA4FQCgSk2FYcpU5ct95pWXIJjM0ObmAghmkRJtNgg6\nHYxTp0EzMmvoKw20dGcg2uuO12igsoTSiYopKTBMCo03q21pMJ9/QSxOEUDwR7f9eyfo9NCPn6B0\n8TNvKzzFX8N8YXB5WMBuh/3jHUj65reCx5tM4EU1NNk54DgOgsEAw+QpEAyG4HvrDdAXjIPKYgmW\nNRpoRo5UPltMtUVMsqvb9DqSJowDbMG/kzMbXwGvEpXXNLy1BZAZNKOywXEcDJMLlZsvjueVz01U\nA/175bVaiL1MvsOpVBBTQzeeHM9HNH44jlP2cAaC3zPLJbOhDRs+iRe07CnKuloOEL4Wz/31cdS+\nthE5qx4Bx3GoeOZJmGZcAMusSzocO9S8lRUQ09KVm4fSB+7FyNvvUtZeRwst3ek/qru+k/0+pGUk\no74h2Cpu2bsHoi1NubFtLSsDr1FDPSKzu7dJWPSd65/ulj3FdD/kRBMeYJnPh5Srr1EeS/n+DyLG\n0qI5Nf/sFrDt+hsgGIxR+3xCYoEX1RFji2cnbmnvMSIkWiggx4hhcmFEOdrj3d0xTjsv1qdACCEJ\nZ1ADMmMMq1atwvHjx6FWq/Hoo49iVNgMTEIIIYR0blBnWW/fvh0+nw+vv/46li9fjjVr1vT8IkII\nIYQMbkDev38/LrkkOClp6tSp+JKWyxBCCCG9MqgB2el0wmQKzSBTqVSQaS9hQgghpEeDOoZsNBrh\nCksvJ8sy+B4ypHQ3BfxcNlyva6hRvfUf1V3/UL31H9Xd4BrUFvI3vvEN7NixAwBw6NAhjB0bP5tT\nE0IIIfFsUBODhM+yBoA1a9YgLy9vsN6eEEIIGbZinqmLEEIIIcN4cwlCCCHkXEIBmRBCCIkDFJAJ\nIYSQOEABmRBCCIkDtLlELwUCAdx///2orKyE3+/HkiVLMGbMGNx3333geR4FBQVYuXIlAGDz5s3Y\ntGkTRFHEkiVLMGfOHMiyjDVr1uDIkSPw+Xy4/fbbcemll8b4qobeQOvN6XRi6dKlcLvd0Gg0WLt2\nLVJSereH6rmuL3UHAI2NjViwYAH+/ve/Q61Ww+v14p577kFDQwOMRiMef/xxJCcnx/CKomegded0\nOnH33XfD5XLB7/fjvvvuw7Rp02J4RdEx0Hprd/LkScyfPx+7d++OeJz0gJFeefPNN9ljjz3GGGPM\nbrezOXPmsCVLlrB9+/YxxhhbsWIF27ZtG6urq2NXXXUV8/v9zOFwsKuuuor5fD62ZcsW9vDDDzPG\nGKupqWGvvPJKzK4lmgZab6+88gpbu3YtY4yxzZs3s8cffzxm1xJtva07xhj7+OOP2Q9+8ANWVFTE\nvF4vY4yxP/3pT2zdunWMMcbeffddtnr16hhcRWwMtO6effZZ5W+0pKSEzZs3LwZXEX0DrTfGGHM4\nHOznP/85u/jiiyMeJz2jLuteuvzyy3HnnXcCACRJgiAIOHr0KKZPnw4AmD17Nnbv3o3Dhw+jqKgI\nKpUKRqMRubm5OHbsGD755BOkpaXhF7/4BVasWIFvfvObsbycqBlIvR0/fhxjx46F0+kEEEzNKopi\nzK4l2npTd3v27AEACIKAl19+GRaLRXn9/v37MXv27A7HJoKB1t0tt9yCG264AUCw1ajRaKJ8BbEx\n0HoDgBUrVmDZsmXQarXRPflhgAJyL+l0Ouj1ejidTtx5551YunQpWNgSboPBAKfTCZfLFZHPu/01\nTU1NOH36NDZs2ICf/vSn+M1vfhOLy4i6gdSbw+FAUlISdu3ahSuvvBIvvvgirrvuulhcRkz0pu4c\nDgcA4KKLLoLFYol43ul0wmg0Kse239gkgoHWndFohFqtRl1dHX79619j+fLlUb+GWBhovT333HOY\nM2cOxo0bF/E46R0KyH1QXV2Nm266CfPmzcOVV14Zkafb5XLBbDbDaDRG/PC1P56UlKS0imfMmIGy\nsrJon37MDKTe1q9fj5/97Gd499138eKLL+K2226LxSXETG/qLhzHccq/w3PLn33DkwgGUncAcPz4\ncfzkJz/B8uXLlRZiIhhIvb3zzjt44403sHjxYtTX1+PWW2+N2nkPBxSQe6n9y3XPPfdg3rx5AIAJ\nEyZg3759AICdO3eiqKgIhYWF2L9/P3w+HxwOB0pKSlBQUICioiIlz/exY8eQmZkZs2uJpoHWm8Vi\nUVp5Vqs1YvOS4a63dRcuvFUSnlt+x44dCRVUBlp3J06cwF133YUnn3wSs2bNit6Jx9hA6+3999/H\nq6++io0bNyI1NRUvvfRS9E5+GKBZ1r20YcMGtLS04Pnnn8f69evBcRweeOABrF69Gn6/H/n5+Zg7\ndy44jsPixYuxcOFCMMawbNkyqNVqXH/99Vi1ahXmz58PAHj44YdjfEXRMdB6u+OOO/Dggw/iL3/5\nCwKBAFavXh3rS4qa3tZduPDWyoIFC3Dvvfdi4cKFUKvVeOqpp6J9CTEz0Lp7+umn4fP58Oijj4Ix\npvTWDHcDrbezH6du676hXNaEEEJIHKAua0IIISQOUEAmhBBC4gAFZEIIISQOUEAmhBBC4gAFZEII\nISQOUEAmhBBC4gCtQyZkmKisrMT3vvc9FBQUgDEGr9eLcePG4aGHHup2h6wbb7wRr776ahTPlBDS\nGWohEzKMpKenY+vWrXjrrbfwr3/9C9nZ2bjjjju6fc2nn34apbMjhHSHWsiEDGO33347Zs2ahePH\nj+PPf/4ziouL0dDQgLy8PKxbtw5r164FAMyfPx+bNm3Czp07sW7dOkiShKysLDzyyCMddvMhhAwN\naiETMoyJoojs7Gx88MEHUKvVeP311/H+++/D4/Fg586dePDBBwEAmzZtQmNjI55++mm89NJL2LJl\nC2bOnKkEbELI0KMWMiHDHMdxmDhxIrKysvDaa6+htLQUp0+fVjbqaM9FfPjwYVRXV+PGG28EYwyy\nLCMpKSmWp05IQqGATMgw5vf7lQD8+9//HjfddBOuvfZaNDU1dThWkiQUFRXh+eefBwD4fL6E2l2L\nkFijLmtChpHwvWIYY1i3bh2mTZuG8vJyXHHFFZg3bx6sViv27dsHSZIAAIIgQJZlTJ06FYcOHVL2\n6l6/fj2eeOKJWFwGIQmJWsiEDCN1dXWYN2+e0uU8ceJEPPXUU6ipqcHy5cvx3nvvQa1WY9q0aaio\nqAAAfOtb38I111yDN998E4899hjuuusuyLKMjIwMGkMmJIpo+0VCCCEkDlCXNSGEEBIHKCATQggh\ncYACMiGEEBIHKCATQgghcYACMiGEEBIHKCATQgghcYACMiGEEBIH/j9PK2OZcai62gAAAABJRU5E\nrkJggg==\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "rolling = goog.rolling(365, center=True)\n", + "\n", + "data = pd.DataFrame({'input': goog,\n", + " 'one-year rolling_mean': rolling.mean(),\n", + " 'one-year rolling_std': rolling.std()})\n", + "ax = data.plot(style=['-', '--', ':'])\n", + "ax.lines[0].set_alpha(0.3)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "As with group-by operations, the ``aggregate()`` and ``apply()`` methods can be used for custom rolling computations." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Where to Learn More\n", + "\n", + "This section has provided only a brief summary of some of the most essential features of time series tools provided by Pandas; for a more complete discussion, you can refer to the [\"Time Series/Date\" section](http://pandas.pydata.org/pandas-docs/stable/timeseries.html) of the Pandas online documentation.\n", + "\n", + "Another excellent resource is the textbook [Python for Data Analysis](http://shop.oreilly.com/product/0636920023784.do) by Wes McKinney (OReilly, 2012).\n", + "Although it is now a few years old, it is an invaluable resource on the use of Pandas.\n", + "In particular, this book emphasizes time series tools in the context of business and finance, and focuses much more on particular details of business calendars, time zones, and related topics.\n", + "\n", + "As always, you can also use the IPython help functionality to explore and try further options available to the functions and methods discussed here. I find this often is the best way to learn a new Python tool." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Example: Visualizing Seattle Bicycle Counts\n", + "\n", + "As a more involved example of working with some time series data, let's take a look at bicycle counts on Seattle's [Fremont Bridge](http://www.openstreetmap.org/#map=17/47.64813/-122.34965).\n", + "This data comes from an automated bicycle counter, installed in late 2012, which has inductive sensors on the east and west sidewalks of the bridge.\n", + "The hourly bicycle counts can be downloaded from http://data.seattle.gov/; here is the [direct link to the dataset](https://data.seattle.gov/Transportation/Fremont-Bridge-Hourly-Bicycle-Counts-by-Month-Octo/65db-xm6k).\n", + "\n", + "As of summer 2016, the CSV can be downloaded as follows:" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# !curl -o FremontBridge.csv https://data.seattle.gov/api/views/65db-xm6k/rows.csv?accessType=DOWNLOAD" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Once this dataset is downloaded, we can use Pandas to read the CSV output into a ``DataFrame``.\n", + "We will specify that we want the Date as an index, and we want these dates to be automatically parsed:" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Fremont Bridge West SidewalkFremont Bridge East Sidewalk
Date
2012-10-03 00:00:004.09.0
2012-10-03 01:00:004.06.0
2012-10-03 02:00:001.01.0
2012-10-03 03:00:002.03.0
2012-10-03 04:00:006.01.0
\n", + "
" + ], + "text/plain": [ + " Fremont Bridge West Sidewalk \\\n", + "Date \n", + "2012-10-03 00:00:00 4.0 \n", + "2012-10-03 01:00:00 4.0 \n", + "2012-10-03 02:00:00 1.0 \n", + "2012-10-03 03:00:00 2.0 \n", + "2012-10-03 04:00:00 6.0 \n", + "\n", + " Fremont Bridge East Sidewalk \n", + "Date \n", + "2012-10-03 00:00:00 9.0 \n", + "2012-10-03 01:00:00 6.0 \n", + "2012-10-03 02:00:00 1.0 \n", + "2012-10-03 03:00:00 3.0 \n", + "2012-10-03 04:00:00 1.0 " + ] + }, + "execution_count": 35, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data = pd.read_csv('FremontBridge.csv', index_col='Date', parse_dates=True)\n", + "data.head()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For convenience, we'll further process this dataset by shortening the column names and adding a \"Total\" column:" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "data.columns = ['West', 'East']\n", + "data['Total'] = data.eval('West + East')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now let's take a look at the summary statistics for this data:" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
WestEastTotal
count35752.00000035752.00000035752.000000
mean61.47026754.410774115.881042
std82.58848477.659796145.392385
min0.0000000.0000000.000000
25%8.0000007.00000016.000000
50%33.00000028.00000065.000000
75%79.00000067.000000151.000000
max825.000000717.0000001186.000000
\n", + "
" + ], + "text/plain": [ + " West East Total\n", + "count 35752.000000 35752.000000 35752.000000\n", + "mean 61.470267 54.410774 115.881042\n", + "std 82.588484 77.659796 145.392385\n", + "min 0.000000 0.000000 0.000000\n", + "25% 8.000000 7.000000 16.000000\n", + "50% 33.000000 28.000000 65.000000\n", + "75% 79.000000 67.000000 151.000000\n", + "max 825.000000 717.000000 1186.000000" + ] + }, + "execution_count": 37, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data.dropna().describe()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Visualizing the data\n", + "\n", + "We can gain some insight into the dataset by visualizing it.\n", + "Let's start by plotting the raw data:" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%matplotlib inline\n", + "import seaborn; seaborn.set()" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\nrpgyZQqUSiWCg4Mxc+ZMAEB0dDQ2bNgAT09PjB07FoMHD3Z2uCQHgsCqBZGTCEYjhOwMqcOgm5ye\n5H/77TcEBATgyy+/RHFxMYYOHYoePXogPDwcISEhmDlzJnbv3o0+ffogKioKW7ZsgVarxQsvvIAH\nHngAnp6ezg6Z5ICd74ic4sacT2BISZE6DLrJ6Un+8ccfx5AhQwAAJpMJjRo1woULFxASEgIAGDhw\nIA4dOgSlUom+ffvCw8MDfn5+CAoKwuXLl9GzZ09nh0xuTi8YURSzX+owiBoEHRO8S3H6NfkmTZrA\nx8cHKpUK7777Lt5//30IFWpZvr6+UKlUUKvV8Pf3tyz38fFBSUmJs8MlGdAZddBdvyZ1GERETidJ\nx7uMjAy8/PLLGD58OJ544gkolf+EoVar0bRpU/j5+UGlUlVZLrXAQH8EBvpbX5FchndesdQhEBFJ\nwulJPjc3F6+//jo++ugjDB8+HABw55134sSJEwCAmJgY9O3bF7169cLJkyeh1+tRUlKCpKQkBAcH\nOzvcKnJySpCTwxYFIiJyfU6/Jv/999+juLgYS5cuxZIlS6BQKDBt2jTMnj0bBoMBXbp0wZAhQ6BQ\nKDB69GiEhYVBEASEh4fDy8vL2eESERG5LYUgyKvb8aGhzzp0+90iVwEArrzxikP3Q0REZIsHtm6q\n8TUOhlNHgskkdQhEREQ2YZKvo5LY41KHQEREZBMm+Toya7VSh0BERGQTJnkiIiKZYpKvI1Mx77km\nIiL3wCRfR3lbt0gdAhERkU2Y5O2QE71e6hCIiIisYpK3Q8GuP6UOgYiIyComeSIiIplikiciIpIp\nJnkiIiKZYpInIiKSKSZ5IiIimWKSJyIikikmeSIiIplikiciIpIpJnkiIiKZYpInIiKSKSZ5IiIi\nmWKSJyIikikmeSIiIplikiciIpIpJnkiIiKZYpInIiKSKSZ5IiIimWKSJyIikikmeSIiIplikici\nIpIpJnkiIiKZYpInIiKSKSZ5IiIimWKSJyIikikmeSIiIplikiciIpIpJnkiIiKZYpInIiKSKSZ5\nIiIimWKSJyIikikPqQOojSAImDVrFi5fvgwvLy/MmTMHHTt2lDosIiIit+DSNfndu3dDr9dj/fr1\n+OCDDzB37lypQyIiInIbLp3kT548iQcffBAAcPfddyM+Pl7iiIiIiNyHSyd5lUoFf39/y3MPDw+Y\n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\nAAAASUVORK5CYII=\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "data.plot()\n", + "plt.ylabel('Hourly Bicycle Count');" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The ~25,000 hourly samples are far too dense for us to make much sense of.\n", + "We can gain more insight by resampling the data to a coarser grid.\n", + "Let's resample by week:" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\nAAAASUVORK5CYII=\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "weekly = data.resample('W').sum()\n", + "weekly.plot(style=[':', '--', '-'])\n", + "plt.ylabel('Weekly bicycle count');" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This shows us some interesting seasonal trends: as you might expect, people bicycle more in the summer than in the winter, and even within a particular season the bicycle use varies from week to week (likely dependent on weather; see [In Depth: Linear Regression](05.06-Linear-Regression.ipynb) where we explore this further).\n", + "\n", + "Another way that comes in handy for aggregating the data is to use a rolling mean, utilizing the ``pd.rolling_mean()`` function.\n", + "Here we'll do a 30 day rolling mean of our data, making sure to center the window:" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\n/wfxJKUnYTfWmQAAAABJRU5ErkJggg==\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "daily = data.resample('D').sum()\n", + "daily.rolling(30, center=True).sum().plot(style=[':', '--', '-'])\n", + "plt.ylabel('mean hourly count');" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The jaggedness of the result is due to the hard cutoff of the window.\n", + "We can get a smoother version of a rolling mean using a window function–for example, a Gaussian window.\n", + "The following code specifies both the width of the window (we chose 50 days) and the width of the Gaussian within the window (we chose 10 days):" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "daily.rolling(50, center=True,\n", + " win_type='gaussian').sum(std=10).plot(style=[':', '--', '-']);" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Digging into the data\n", + "\n", + "While these smoothed data views are useful to get an idea of the general trend in the data, they hide much of the interesting structure.\n", + "For example, we might want to look at the average traffic as a function of the time of day.\n", + "We can do this using the GroupBy functionality discussed in [Aggregation and Grouping](03.08-Aggregation-and-Grouping.ipynb):" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\nLi9evLjdx/SXOpPl1u+1O+64Q96yZYssy7J8zz33yN98802bx/TXenvllVfkK664ovG+Wrp0qZyR\nkSHLsiy/99578mOPPdbs9aLOGpxbb6tXr5Y3bNggy7Isb9++Xf7222+bvV7Umyx/8MEH8p///GdZ\nlmW5urpavvjii0U86IIOd1mfna965MiRpKWlkZ6ezvjxDTmeZ8yYwbZt2wBYtWoVRUVFLXJcHz58\nGIDDhw979Dhf1dr7qKqq4m9/+xu///3vm7129erVos5Oa+1eGzJkCJWVlciyjM1mQ61u6OQR9dYk\nISGB559/vvHxM888Q0pKw17iLpcL3ek9v8XfZ3Pn1tvevXspKipixYoVfPbZZ0ya1LCvuLjXmixY\nsIA777wTALfbjUqlEvGgCzockK1WK35+TenNVCoV8llLmU0mEzU1DflIn3jiCSIjI1s9xu12e/w4\nX3Xu+1AoFKxevZrVq1djMBiavZ/HH39c1Nlprb2XmJgYHn30US6//HIqKiqYOHEiIOrtbHPnzkWl\natoHOzQ0FGgIMO+88w433ngjIP4+z3VuveXn5xMYGMhrr71GZGQkL7/8MiDutbMZDAaMRiNWq5U7\n77yTu+66S8SDLuhwQL5QvmqbzYa/v/8Fj1GpVF47ztec+z6qqqrIz8/nwQcf5J577uHYsWM89thj\n5z2mv9UZtP5ennzySd555x3Wr1/PVVddxeOPP37BY/pbvbVm/fr1PPTQQ7z88ssEBQU1e07UWesC\nAwOZNWsW0LBRzpkW2Rmi3hoUFhayfPlyFi5cyOWXXy7iQRd0OCCfm686JSWFIUOGsHPnTgC2bNnC\nuHHjznvMmRzXQ4cOZdeuXR4/ztec+z4mTpzIp59+yhtvvMHTTz/N4MGDWbNmzXmP6W91Bq2/l4CA\nAEwmEwARERFYLJYLHgP9q97OtW7dOt5++23efPNNYmJiWjwv6qx148aNa3x/u3btYvDgwc2eF/UG\nZWVl3Hzzzdx7770sXLgQgCFDhnjl/felemtTRwedJUmS//jHP8qLFy+WFy9eLB8/flzOycmRly5d\nKi9evFi+7777ZEmSZFmW5f/7v/+TCwsLWz1GlmWPH+er2nofsizLp06dajapS9RZk9bey549e+Ql\nS5bIS5culW+66SY5Pz9flmVRb+c6c1+53W554sSJ8tVXXy0vXbpUXrZsmfyPf/xDlmVRZ605++8x\nPz9fXrFihbxkyRL5lltukS0WiyzLot7O9sgjj8jTpk2Tly1b1nh/ZWRkiHjQSSKXtSAIgiD4AJEY\nRBAEQRB8gAjIgiAIguADREAWBEEQBB8gArIgCIIg+AARkAVBEATBB4iALAiCIAg+QARkQehDrFYr\nt99+O6WlpfzqV7/q6eIIgtABIiALQh9SVVVFRkYGYWFhvPTSSz1dHEEQOkAkBhGEPmTlypX88MMP\nzJw5k/T0dDZv3syaNWswGAzs2bOHmpoa7rvvPtatW0dmZiaXXHIJq1ataswTvnPnTiRJYuHChSxf\nvryn344g9CuihSwIfcj9999PeHg49913HwqFovH3paWlrFu3jt/85jesWbOGhx9+mI8++oi1a9di\ntVpZu3YtCoWCDz/8kLVr17Jp0yb27NnTg+9EEPofdU8XQBAEzzu342vGjBkAREdHk5yc3LjjU2Bg\nIBaLha1bt5KZmdm4l6zdbicrK6t3J+oXhF5GBGRB6IPObh0DaDSaxp/P3vP3DEmSuPfee5kzZw4A\nlZWVjbtqCYLQPUSXtSD0IWq1unHT9vZMDznzmsmTJ/P+++/jcrmw2WzccMMNHDhwwNvFFQThLKKF\nLAh9SEhICFFRUaxZs6bZxu1tOdOSXrJkCXl5eSxcuBC32821117LhAkTvF1cQRDOImZZC4IgCIIP\nEF3WgiAIguADREAWBEEQBB8gArIgCIIg+AARkAVBEATBB4iALAiCIAg+QARkQRAEQfABIiALgiAI\ngg/4f1unlzCpFZdIAAAAAElFTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "by_time = data.groupby(data.index.time).mean()\n", + "hourly_ticks = 4 * 60 * 60 * np.arange(6)\n", + "by_time.plot(xticks=hourly_ticks, style=[':', '--', '-']);" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The hourly traffic is a strongly bimodal distribution, with peaks around 8:00 in the morning and 5:00 in the evening.\n", + "This is likely evidence of a strong component of commuter traffic crossing the bridge.\n", + "This is further evidenced by the differences between the western sidewalk (generally used going toward downtown Seattle), which peaks more strongly in the morning, and the eastern sidewalk (generally used going away from downtown Seattle), which peaks more strongly in the evening.\n", + "\n", + "We also might be curious about how things change based on the day of the week. Again, we can do this with a simple groupby:" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\n8BD/A/9r7TmuhSCKAAAAAElFTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "by_weekday = data.groupby(data.index.dayofweek).mean()\n", + "by_weekday.index = ['Mon', 'Tues', 'Wed', 'Thurs', 'Fri', 'Sat', 'Sun']\n", + "by_weekday.plot(style=[':', '--', '-']);" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This shows a strong distinction between weekday and weekend totals, with around twice as many average riders crossing the bridge on Monday through Friday than on Saturday and Sunday.\n", + "\n", + "With this in mind, let's do a compound GroupBy and look at the hourly trend on weekdays versus weekends.\n", + "We'll start by grouping by both a flag marking the weekend, and the time of day:" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "weekend = np.where(data.index.weekday < 5, 'Weekday', 'Weekend')\n", + "by_time = data.groupby([weekend, data.index.time]).mean()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we'll use some of the Matplotlib tools described in [Multiple Subplots](04.08-Multiple-Subplots.ipynb) to plot two panels side by side:" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAzMAAAFRCAYAAABACPPOAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzs3XlgVOX18PHvnS0zyUz2jT0sAZRFlggIqLggoIiK8lYQ\n1F+1Cq3d0FZtqWhrW61rF7tYrNa4QV2KuxYFUVkVCCoIgYBhy74ns899/wgzgEAySWZyZzmff3Qm\nd+49dybkzrnPc86jqKqqIoQQQgghhBBRRqd1AEIIIYQQQgjRGZLMCCGEEEIIIaKSJDNCCCGEEEKI\nqCTJjBBCCCGEECIqSTIjhBBCCCGEiEqSzAghhBBCCCGikiQzIuZ873vf49lnnw083r9/P0OHDuWx\nxx4LPFdTU8Pw4cNpamrq8P5fe+01Fi5c2O52//rXv7j77rs7vH8hhBCxK1KuUZ1RW1vL0KFDw7Jv\nITpLkhkRc8477zw2bdoUeLx69WouvPBCPvzww8BzGzZsYOzYsVitVi1CFEIIEaei+RqlqiqKomgd\nhhAnkGRGxJzzzjuPzZs3Bx5/+OGH3HLLLTQ3N3Pw4EEA1q9fz5QpUygvL+e2227j6quv5oorruDJ\nJ58MvG7r1q1cd911zJ49m2uuuYaPPvropGO9++67XHLJJezfvx+Px8PSpUu55JJLmDt3Llu2bAls\nt23bNubPn893vvMdLrzwQpYsWQLA3//+d26//fbAdp9//jlXXXUVPp+PpUuXMmvWLK6++mp+8pOf\nYLfbQ/5eCSGE6F5aXaMAXn75ZWbPns3s2bP57ne/y759+wC4++67uf/++7n++uu55JJLWLhwYeCa\n8/7773PppZdy9dVX88c//jGw76qqKm666abA/o7/mRDdShUiBl1yySXqzp071fr6enXy5Mmqqqrq\nPffcoz7zzDOqqqrqRRddpO7du1e9/vrr1dWrV6uqqqpOp1O9/vrr1XfeeUetr69Xp02bph46dEhV\nVVUtLy9Xzz//fPXIkSPqq6++qt56663qG2+8oc6cOVMtKytTVVVVn3nmGfXGG29UPR6P2tLSol51\n1VXqXXfdpaqqqi5evFjdtGmTqqqq2tzcrE6YMEH96quv1OrqarWgoECtr69XVVVVf/7zn6srVqxQ\nN2/erM6YMSNwPg8//LC6devW8L9xQgghwk6La9SmTZvU6667TnU4HKqqquonn3yiXnrppaqqqupd\nd92lzp07V3W73arb7Vavuuoq9dVXX1WrqqrUgoICde/evaqqquo//vEPdejQoaqqquoTTzyhLl26\nVFVVVW1paVEXL16sNjY2hv/NE+JbDFonU0KEw7nnnsumTZtIT09n0qRJAFxwwQW88MILXHzxxSiK\nQo8ePdi8eTMNDQ08/vjjANjtdnbu3InFYqGyspIf/OAHqKoKgE6nY9euXQB88cUXfPLJJ9x9993k\n5OQArXfSZs6ciV6vx2KxMGvWrMD2DzzwAB999BH/+Mc/KCkpweFw0NLSQnp6OlOmTGHlypVcccUV\nfPLJJ9x77714PB70ej1z5sxh8uTJTJ06lZEjR3b32yiEECIMtLhGrVmzhtLSUq699trAaxoaGmho\naAjEZDC0fi0cPHgw9fX1fP755wwZMoQBAwYA8J3vfCdQ23Puuedy6623cvjwYSZOnMjtt98ecdPi\nRHyQZEbEpHPPPZeXX34Zk8nE1KlTAZgwYQJLlixh3bp1nH/++Xi9XgCWL1+OyWQCWosbzWYzGzZs\nYNCgQSxfvjywz4qKCjIyMnj99ddJTk7m0Ucf5cc//jEXXHABPXv2RFGUwAUCQK/XB/5/3rx5nHHG\nGZx33nnMmDGDoqKiwLbz5s3j3nvvRafTMW3aNCwWCwArV65ky5YtbNiwgZ/+9Kdcf/313HDDDeF9\n44QQQoSdFtcon8/HFVdcccLU5vLycpKTkwEwm82B5/3XM0VR8Pl8geePv66NGDGCDz74gHXr1rFh\nwwauueYa/vrXvzJq1KgwvGNCnJ7UzIiYNGHCBHbu3Mlnn33G5MmTgdY/1MOGDeP5559nypQpWK1W\nzjrrLJ566img9Q7V3Llz+eCDDzjrrLPYv38/n332GQA7d+5k2rRpVFRUANCvXz/Gjx/P/Pnz+fnP\nf46qqpx77rmsXLkSl8uF0+nk7bffDux3x44d/OxnP+Piiy+mrKyM0tLSwIVq9OjR6HQ6nn76aebO\nnQu03kG74YYbGD16NLfddhtXXnklX3/9dbe+h0IIIcKju69RAJMmTeKtt96isrISgOeff54bb7yx\nzTjHjh3L3r17AyM+r776auBnjzzyCE888QQXXXQRv/zlLxk0aFCgNkeI7iQjMyImJSQkkJeXh9fr\nPWHY+/zzz+ehhx5i3LhxQOsf41//+tdcfvnleDweLr/8cmbOnAnAn//8Z/7whz/gdDpRVZWHHnqI\nHj16nHCcRYsWsXr1ap566iluuukmSktLmTlzJmlpafTr1w+A5ORkbrnlFq688krS0tJIS0tj7Nix\nlJaWMmHCBABmz57NO++8Q35+PtBaIPrxxx8zc+ZMEhMTSU1N5Te/+U3Y3zchhBDh193XqGXLlnHz\nzTdz8803893vfhedTofVauUvf/lLm3Gmp6fz8MMPc8cdd2A0GgNxAdxwww3ceeedXH755ZhMJoYO\nHcpll10WqrdIiKAp6vHzYoQQ3c7j8XDbbbdxxRVXMGPGDK3DEUIIIYSIGkGNzMyePTtw56B3794s\nXLiQu+66C51OR35+PkuXLgVgxYoVLF++HKPRyMKFC5kyZUrYAhciFuzdu5e5c+cyZcoUSWSE6IKi\noiIefvhhCgsLqampYcmSJTQ2NuL1ennwwQfp06ePXKOEECIGtZvMuFwugBNWq120aBGLFy+moKCA\npUuXsmrVKkaNGkVhYSGvvfYaDoeDuXPnMmnSJIxGY/iiFyLKDRw48ITF04QQHbds2TJWrlxJUlIS\nAA899BCzZs1i+vTpbNy4kZKSEiwWi1yjhBAiBrXbAODrr7+mpaWFm266iRtvvJGioiJ27NhBQUEB\n0Dq3f926dWzfvp2xY8diMBiwWq3k5eUFCsaEEEKIcOnXrx9PPPFE4PGWLVsoKyvj//7v/3jzzTcZ\nP368XKOEECJGtZvMmM1mbrrpJp566inuvfde7rjjjhPazyYlJdHU1ERzczM2my3wfGJiIo2NjeGJ\nWgghhDhq6tSpJ7SMPXToEKmpqTz99NPk5uby5JNP0tTUJNcoIYSIQe0mM3l5ecyaNSvw/6mpqVRX\nVwd+3tzcTHJyMlarlaamppOeb4v0HhBCHM/T3EzJsn/hqqvXOhQRxVJTU7ngggsAuPDCC/nyyy+x\n2WwdvkaBXKeEECLStVsz88orr7B7926WLl1KeXk5TU1NTJo0iU2bNjFu3DjWrl3LhAkTGDFiBI89\n9lhgjY2SkpJAm9nTURSFysr4uzOWlWWT844T8XjO0Pnzrv9kLeVvvIVLn0DGzFlhiCy8ovXzzsqy\ntb9RFBk7diwfffQRs2bNYvPmzeTn53fqGgVynYo38Xje8XjOIOcdbdq6TrWbzFxzzTXcfffdzJs3\nD51OxwMPPEBqaipLlizB7XYzcOBApk+fjqIoLFiwgHnz5qGqKosXLw6sWCuEEMFwHx31dZZ+o3Ek\nIprdeeedLFmyhBdffBGbzcYjjzyCzWaTa5QQQsQgzdeZicbssKuiNSvuqng873g8Z+j8eZc9/RQN\nn36MMTOL/g88FIbIwitaP+9YG5kJtWj8TLsqWn+XuyoezzsezxnkvKNNW9epdmtmhBCiu3hqWkdm\n3FWVeJubNY5GCCGEEJFOkhkhRMRw1xxrLuI8UKphJEIIIYSIBpLMCCEigqqqeGpqAo+lbkYIIYQQ\n7ZFkRggREbxNjahuN6aevQBwSDIjhBBCiHZIMiOEiAie6tZRmcShZ6AkmHGWyjQzIYQQQrRNkhkh\nRETw18sYMzNJ6NMH15HD+JxOjaPqHj/+8ff5+usdAHg8HqZPn8KLLz4X+PkPf3gre/YUB72/V15Z\nEfIYhRBCxK9Ivk5JMiOEiAj+TmaG9HTMffuCquI8dFDjqLrHuHHjKSraCkBR0VbGjz+HDRs+BcDl\nclFeXsagQe0v8Oj37LNPhSVOIYQQ8SmSr1OSzAghIoKn2p/MZJDQNw/QrgnAz/66LqSP21NQMJ6i\nom0ArF//KTNnXkljYyMtLc18+eV2Ro0aw7ZtW/j+92/mhz+8lQce+A1er5cDB0pZtOgmfvjDW7nt\ntluorKzg2Wf/RUNDA48++mCHYhBCCBE95Dp1jCEkexFCiC5y17bWzBjTM1AMrX+a4qVuZvDgIZSW\n7gegqGgLCxfeRkHBODZv3siePcWMGzeBBx+8n7/97V+kpqaybNnfefvtN3C73Zx55nC+//0fUVS0\nlaamJq6//ru88soKFi++U9uTEkIIETMi+TolIzNCiIjgqakGvR59cjIJPXuBXq9ZR7OHvj8xpI/b\noygKAwfms2HDOjIyMjEYDEyYMJHt24v44osiCgrGU11dzT333MWPfrSQzZs3Ul5exuWXX4nVamXx\n4h/y6qsr0Ov1R/eoduj4Qgghootcp46RZEYIERHc1TUY09NRdDoUg4GEXr1xHTyA6vFoHVq3OPvs\ncRQWPs2ECa0XmJEjR7F799eoqkpKSgrZ2Tk88MAj/OlPf2fBgv9jzJgC1q5dw1lnjeaPf/wrU6Zc\nxPPP/xsAVXIZIYQQIRap1ylJZoQQmvO53Xjr6zCkZwSeS+jbF9XjwVV2RMPIuk9BwQS++KKICRMm\nA2AwGLDZkhk9eiyKovDjHy/mjjt+zKJF3+W//32ZAQMGMXToGSxb9nd+/ONFrFz5Ktdccy0A/fsP\n4De/uUfL0xFCCBFjIvU6paiqtvfwKisbtTy8JrKybHLecSIezxk6ft6uygr23/1zbOdMpMdNtwBQ\n9+EqKl54jtzvfo/kiZPCFWpIRevnnZVl0zqEiBaNn2lXRevvclfF43nH4zmDnHe0aes6JSMzQgjN\neWqOFf/7JfTtB6BZ3YwQQgghIp8kM0IIzR1bY+a4ZKZ3H1AUzdozCyGEECLySTIjhNCc++gaM8aM\n9MBzOrMZY04OzgOlqD6fVqEJIYQQIoJJMiOE0Jx/mtnxIzMA5r55+Ox23FVVWoQlhBBCiAgnyYwQ\nQnPuo9PMjOnpJzyf0LcvgEw1E0IIIcQpSTIjhNCcp6YGXWIiOrPlhOf9TQAkmRFCCCHEqRi0DkAI\nEd9UVcVdXY0xK+ukn5njqKPZ1q2fc889d9O//wD8HfPT0tL59a9/H/Q+1q5dw7Bhw8nIyAxXmEII\nIeJUpF6nJJkRQmjKZ29BdTpOmmIGoLdaMaRnxM3IzNixZ3Pvvb/t9Ov/858Xycv7hSQzQgghwiIS\nr1OSzAghNOWpPlr8n5Fxyp8n9O1L87ateOrqMKSmdktMv1p36rtMv5l4d5vb63UKXp/a7vanc6o1\njLdt28LTT/8TVVWx21tYuvS3ZGfncM89d9Hc3IzD4eCWW76Px+OmuHg399+/lL/+dRkGg/x5F0JE\nJq/dTv2a1ThK9mIZMgTrqNEYM08enRenJ9epY+RqJ4TQVKD4P+3kkRlonWrWvG0rjtL9WFNHdWdo\n3W7Lls/40Y8WoqoqiqJwzjmTsVjM3HPPb8jIyKSw8GlWr17F5MnnU19fzyOP/Jna2hoOHCjlnHMm\nM3jwEH72s19IIiOEiEie+nrqPvgfdas/wGe3A9C09XMqX3oBU+8+WEeNxjp6DAl9+6EoisbRilOJ\nxOuUXPGEEJoKLJh52pEZfxOAUqwjuyeZ6eidKv/2WVk2KisbO33cUw3ff/LJRzz22EMkJiZSWVnB\nyJGj6N9/ALNmXcW99/4Cj8fLnDnfAVrvmJ3qrpkQQmjJXVlJzfvv0PDJx6huN3pbMpmzL8M6poCW\nXV/TvG0LLTt3UPPmAWrefB1DejpJZ43GOmo0iUOGosgNmpPIdeoY+e0QQmjKfXSNGWN6e8lM7NfN\nnOoP/IMP/pYVK1ZisVj47W/vRVVVSkr20NLSwh/+8DjV1VUsWnQT55wzGZ1OJ8mMECJiOA8eoOad\nt2ncvBF8PoyZWaRNm0HypMnoTCYATLm5pJ4/BZ/DTvOXX9K0bQvN27dTv/oD6ld/gM5iIWnEWa2J\nzYiR6C2Wdo4qwikSr1OSzAghNBUYmTlNMmNIS0NvteEsLe3OsDSxdevn/OhHCwECQ/iXXDKD73//\nJiyWRNLT06mqqqRPn37861//ZPXqVaiqys03LwJg+PCR3H//PTz66BPYbDYtT0UIEcfsxcXUvPMm\nzduLADD16k36pZdhKxiHotef8jU6swVbwdnYCs5G9XiwF++madtWmrZtoXHTBho3bQC9nsShZ2Ad\nNZqks0afsnGMCK9IvE4pqsa38boy1BWtujrEF63i8bzj8ZyhY+d94MHfYd9TTP7fl532Infw0Ydo\n2fEVA//4BPqkpFCGGlLR+nlnZUni05Zo/Ey7Klp/l7sqHs87VOesqirNX2yn9p23sBfvBsCSP5i0\nGZeSNOKsTtfAqKqK6+CB1sRm65YTRunTZ15O5pVXd2q/8fhZQ/Sed1vXKRmZEUJoyl1djSE17bSJ\nDLRONWvZ8RXOA6UkDj2jG6MT0aKoqIiHH36YwsLCwHNvvPEGzz//PC+99BIAK1asYPny5RiNRhYu\nXMiUKVM0ilaI2KF6vTR+tomat9/CdeggAEkjzyJ9xmVY8gd3ef+KopDQpy8JffqScfkVuKuraSra\nSt3771Hz5huY8wZgHTW6y8cR0UuSGdEtPHW1qBmRe0ddaEP1+fDU1WLuP6DN7RL69gVa62YkmRHf\ntmzZMlauXEnScaN2O3bs4JVXXgk8rqqqorCwkNdeew2Hw8HcuXOZNGkSRqNRi5CFiHqqqtKw7hNq\n3ngdd1Ul6HTYxp9D+vRLSejTJ2zHNWZkkHbhxSTmD6H0t/dR9sxT9Lvn1zLlLI7ptA5AxD773j2U\n/GwxlWvWah2KiDCeurrWotDTdDLzM/fNA8ARB00ARMf169ePJ554IvC4traWxx9/nF/+8peB57Zv\n387YsWMxGAxYrVby8vLYtWuXFuEKEfVUr5eK5wspf/opPPV1pFxwIXm/fYAe37s1rInM8RL69CHr\nO/PwNTVRtuwfqF5vtxxXRB5JZkTYNX9RBKpK4+7dWociIkx7xf9+xuxslARzXDQBEB03depU9Een\nKfp8PpYsWcJdd92F5biuR01NTScUmyYmJtLYGH3zxoXQms9h59Cf/0j9mg9J6NOHvPsfIOe66zFl\nZXd7LClTLsA6tgD77l1Uv/l6tx9fRAaZZibCzl5cDIDjSBnJGsciIktgwcx2pgcoOh0Jffrg2LsH\nn9OJLiGhO8ITUeirr76itLSUe++9F6fTyd69e/n973/P+PHjaWpqCmzX3NxMcnJwf5HitUGCnHf8\nCPacnVXV7Hj4AVr2f0Pa2NEMvuN2DInatkpOX/xDtv30DmreeoOe48eQMmJ40K+Nx88aYu+8JZkR\nYaV6PDj2lQDgKCvTOBoRaTzVrWvMtDcyA2Du2xfHnmKchw5iGTAw3KGJKKSqKiNGjOCNN94A4NCh\nQ9x+++3cfffdVFVV8fjjj+NyuXA6nZSUlJCfnx/UfqOx809XRWvHo66Kx/MO9pwdpd9w6E+P4a2r\nI2XKhWTOvY7aZg80a/9+Zd90Kwce/B07H36Mfkt/jcHW/o2KePysIXrPW7qZCc04Sr9Bdbla/7+i\nEtXjkZV8RYA7MM2s/cLNhKN1M87Sb2IumfnLXx5n166d1NRU43A46NWrN6mpafz6178/aduysiOU\nlOxl4sTJp9zXoUMH+e1v7+Wvf10W7rAjTlutXzMzM1mwYAHz5s1DVVUWL16M6eiifUKItjUVbePI\nk39DdbnI+n/Xkjp1WqdbLYeDZeAgMq+6mqpX/kP5v5bR84c/QdFJJUWoReq1Sr5VirDy95rXWSz4\n7Hbc1VWYcnI1jkpECk9t68iMMYiRmWMdzWKvbua2234CwDvvvElp6TfceusPTrvtZ59t5MiRI6e9\nQEDbX+pjVa9evQItmE/33Jw5c5gzZ053hyZEVKv94H9UvvQCitFIj0W3YRszVuuQTilt2gxadu6g\n+Yvt1K16n7RLpmsdUsyJ1GuVJDMirOx7WutlbGePp37tGtyVFZLMiABPdTVKQgK6IBbCTOjZC/T6\nsHc0q/zPSzR+trlTr/1Gr8Pr9Z30vK3gbLLmXNvh/f3pT4/w5ZdfoCgK06ZdyqxZV/HCC4W43W6G\nDx9JQkIC//73U/h8PhwOB/fe+9tOxS2EEN+m+nxUrniRulX/Q5+cTK8f/qTdNvpaUnQ6cm+6hW/u\n+xWVr/wHS/7giI63KyLpOgXaX6tkDE6EjaqqOIqLMaRnYBkyFABXRYXGUYlI4q6pxpieEdTdGcVg\nIKFXb1wHD6B6PN0QnbY+/ngN1dVVPPnkMzzxxD95++03OHToIPPmLWDatEs555xJ7NtXwr33/o4/\n//kfTJp0Lh999KHWYQshYoDP6eTwX/9M3ar/YerZk76/+FVUJAaGlBRyb74VfD6OPPk3vC0tWocU\n8yLhWiUjMyJs3OVleJsasY2fgCm7tWWju6Jc46hEpPA5HPiamzHk9Q/6NQl9++Es/QZX2RESeodn\nLYOsOdd2+u5UKAsr9+/fz8iRrataGwwGzjxzGPv37zthm8zMLB599EEsFgsVFeWMGVMQkmMLIeKX\np66WQ396vHWR4jOG0WPR99EnRs+i10lnDiN9xmXUvP0mFYXPkHvLopibehsp1ymIjGuVjMyIsLEf\nXVfGMmgwxuwcANwyMiOOctf4O5kFv2qzOYbrZr4tLy+P7du3AeDxePjyyy/o06cPiqLD52udIvDQ\nQ79lyZJ7+cUvlpKenoGqqgCB/wohREc4Dx6g9He/wVn6DcmTz6PXj38aVYmMX8asKzEPHETj5k00\nfCwLdodTJFyrZGRGhI19z9FkJj8ffVISBptVkhkR0JHif7+Evv0AcJTuJ3nipLDEFSnOPXcK27Zt\nYdGi7+J2e5g2bQYDBgzC5XLzwgvPMnjwEKZOncGiRTdhNltIS0ujqqoKiM8GAEKIrmn+8guO/P0J\nfA4HmbOvIW3GZVH7t0QxGOhxy0K+ue8eKl56HvPAQST06qV1WDEpEq5ViqrxLbxo7HXdVdHa47uj\n9t39c7zNTQx8/C8oOh2HH7yf5n37GfTXJ+OmZWK8fNbfFsx516/9iPJnnybn/24mZdLpu50cz+dw\nsOeHi7DkD6bPz+8ORaghFa2fd6wtoBZq0fiZdlW0/i53VTyed1aWjeKXX6fi+cJAEb3t7HFahxUS\njZ9/xpG//QVTz170/eU9Jyy4HI+fNUTvebd1nYqPb5Si23nq6nBXVmAZlB9IXMw9clE9nsAdeRHf\n/GvMGDOCH5nRmc2YcnJxHihF9Z3cjUUIIUTwVJ+P/c88S0Xhv9EnJtH7jjtjJpEBsI0tIOWCi3Ad\nPkTl8he1DkeEiSQzIiz8LZktg46tsG3ObW3JLFPNBIDHv2BmWvA1M9A61cxnt+M+OkwthBCic6pf\n/y+HXluJMTeXPr/41QnX7FiR9f++g6l3H+rXrqFx8yatwxFhIMmMCItj9TKDA89ZevQApD2zaHWs\nAUBah153bPHM8K43I4QQsaxl9y5q3nqDhOxs+t61JNB1NNbojCZ63roIxWSi/NmncVXKd5BYI8mM\nCAt7cXHruiB5eYHnzD38IzPSnlm0LpipT05GZzR16HX+JgCSzAghROd4W5opW/YkAIMX/xi91apx\nROFl6tGT7Ouux2e3c+Qff4uLtcriiSQzIuR8DjvO0m9IyOt/whfVY8mM3BWJd6rPh6e2BkMHOpn5\nmQMdzSSZEUKIjlJVlYrnnsVTU036zFkknzFU65C6RfLESdgmnINz/z6qXntZ63BECEkyI0LOXlIC\nqnrS3FtjSgpKghmXjMzEPW9jI6rH06Hifz+91YohPUNGZoQQohMaN6yjcdNGzAMHkTFzltbhdBtF\nUciZfz3GnBxq33uX2s+3aB2SCJGgkpnq6mqmTJnCvn37KC0tZd68ecyfP5/77rsvsM2KFSu4+uqr\nufbaa1mzZk244hVRwF58cr0MtP4hMWVn466skEX94lyg+L8TIzPQWjfjbWjAU1cXyrCEECKmuSor\nqHi+EJ3ZTO7Nt6Do9VqH1K10Zgs9blmEYjCw+/E/421p0TokEQLtJjMej4elS5diNpsB+P3vf8/i\nxYt57rnn8Pl8rFq1iqqqKgoLC1m+fDnLli3jkUcewe12hz14EZkc/k5mAwed9DNjdjaqy4W3vr67\nwxIRJNCWuYOdzPzMxy2eKYQQon2q10vZsifxORxkX7cAU1ZsFvy3x9wvj/TLLsfT0ED92jVahyNC\noN1k5sEHH2Tu3LlkZ2ejqio7duygoKAAgPPOO49169axfft2xo4di8FgwGq1kpeXx65du8IevIg8\nqseDfe8eTD17nbKg0Hj0j6dMNYtvnuqjncwyOpfMHGsCUBqymIQQIpZVv/k6jr17sI2bgG3CRK3D\n0VTqhRejM5upXfU+Prn5HvXaTGZeffVVMjIymDRpUmBakO+4heqSkpJoamqiubkZm+3YypyJiYk0\nNkbf6qKi65wHSlFdLiz5p+5Vb8rOAcAtrRHjmvvowqnGTk8zk45mQggRLHtxMTVvvo4hI4Ps+QtQ\nFEXrkDSlT0oid9pUvHV1NG5cr3U4oovaTWY+/fRTFixYwK5du7jzzjupra0N/Ly5uZnk5GSsVitN\nTU0nPS/ij73Yv1jm4FP+3Hi0j710NItvXa2ZMaSlobfaZGRGCCHa4W1p4chT/wAg96Zb0CcmaRxR\nZOh5+UzQ66l99x3U427Ui+hjaOuHzz33XOD/r7/+eu677z7+8Ic/sHnzZs4++2zWrl3LhAkTGDFi\nBI899hgulwun00lJSQn5p7kz/21ZWbb2N4pBsXre1QdKAOg1YTTmU5xj7tABHAR09TUx+x58W7yc\n57e1dd6HoxheAAAgAElEQVSHG+pQjEZyB/RE0XWuqWLloAHUbSsizaJgiKA1EuL18xZCRKaK5wvx\nVFWRPvNyEgcP0TqciJGQlUny+Ak0rPuU5u1FWEeN1jok0UltJjOncuedd/KrX/0Kt9vNwIEDmT59\nOoqisGDBAubNm4eqqixevBiTKbiF8Cor4286WlaWLSbPW1VV6r7ciSEtnQbMNH7rHLOybNT7jCgG\nA40HDsXke/BtsfpZt6e987aXV2BITaOqurnTx1ByewFFHNq6g8ShZ3R6P6EUrZ+3JGBCxKaGDeto\n3Lge84ABZMy8QutwIk7atBk0rPuUmnfflmQmigWdzDz77LOB/y8sLDzp53PmzGHOnDmhiUpEJXdF\nOd7GBmzjxp92Pq6i02HMzsZdUY6qqnE/bzce+dxuvA0NmIb26tJ+zMfVzURKMiOEEJHCXVlJxfOF\nKAlmcm9eiGLo8P3rmJfQqzdJI8+ieXsR9uLi09b7isgmi2aKkDlWL9P2HwNjVjY+ux1fc+fvyovo\n5Tlad2dM71wnM7+EQHtmaQIghBDHU71ejjz1JD67nex58zFlx2cb5mCkTb8UgJr33tY4EtFZksyI\nkLHvOfVimd9mPNrRTNozx6euFv/7GbOzURLM0gRACCG+pebtN3HsKcZaMI7kiZO0DieiWfIHYx4w\nkOZtW3EePqx1OKITJJkRIWMvLkZnsWDq1bvN7UyBjmaSzMQjd/XRBTO7mMwoOh0JffrgOnIYn9MZ\nitCEECLq2ffuofqNlRjS08lZcINM526HoiiB0Zna997ROBrRGZLMiJDwNDTgLi/DPHBQu92pjIG1\nZiq7IzQRYY6NzHRtmhkcrZtRVZyHDnZ5X0IIEe28djtl//wHqGprG+YkacMcDOuo0RhzcmnYsA73\ncUuQiOggyYwICXvx0Slm7dTLQGvNDMg0s3jlDtE0M5DFM4UQ4ngVLxTirqokfcZlJA4ZqnU4UUPR\n6UifNgO8XupWva91OKKDJJkRIWHfc7T4v516GQBjRgbo9bJwZpzy1NQAXW8AAJDQty+A1M0IIeJe\nw8YNNK5fR0JefzJmXal1OFHHds456FNSqP9oNd6WFq3DER0gyYwICXvxbtDrMef1b3dbRa/HmJEp\nNTNxylNTgy4pCZ3Z3OV9JfTsBXq9dDQTFBUVsWDBAgB27tzJddddx/XXX8/NN99MzdEEesWKFVx9\n9dVce+21rFmzRsNohQgtd3UVFc/9GyUhgR7fkzbMnaEzmki7+BJ8Dgf1H63WOhzRAZLMiC7zOZ04\nS7/B3C8PXUJCUK8xZmfjbWzEa7eHOToRSVRVxV1T3eXifz/FYCChV29cBw+gejwh2aeIPsuWLWPJ\nkiW43W4Afve733HPPffw7LPPMnXqVP75z39SVVVFYWEhy5cvZ9myZTzyyCOB7YWIZqrPR9myo22Y\n587HlJOjdUhRK+X8KejMZmpXvY9P/j5EDUlmRJc5SvaCzxfUFDM/f92Mu1KmmsUTX3MzqtMZkuJ/\nv4S+/VA9HlxlR0K2TxFd+vXrxxNPPBF4/NhjjzFkyBAAPB4PJpOJ7du3M3bsWAwGA1arlby8PHbt\n2qVVyEKETM3bb2Iv3o11bAHJkyZrHU5U0ycmkXL+FLz19TRuWKd1OCJIksyILutIvYyftGeOT6Es\n/vczS91M3Js6dSp6vT7wODMzE4AtW7bwwgsvcOONN9LU1ITNZgtsk5iYSGNjY7fHKkQouWtrqXnr\nDfSpqeQsuFHaMIdA6sXTQK+n5r13UH0+rcMRQZBkRnRZoJPZwEFBvybQnlmaAMSVY8X/oUtm/B3N\nHKX7Q7ZPEf3efvtt7rvvPp588knS0tKwWq00NTUFft7c3ExycrKGEQrRdTVvv4HqdpN55Wz0VqvW\n4cQEY1oayRMm4i4ro7loq9bhiCBIhZjoEtXrxb53L6YePdEfd9ezPcfaM0syE08Ca8xkhHCaWe8+\noCgyMiMCVq5cyYoVKygsLAwkLCNHjuTxxx/H5XLhdDopKSkhP7/9VvIAWVnB/22LJXLekc1RXkHx\nx2sx98hl4KzpKMeNTnZUtJxzqJ3uvJPmXsPWTz+mcdV75E09P+ZGvGLt85ZkRnSJ8+ABVKcDS5Bf\nCvyMWZmgKDLNLM64wzAyozObMeXk4jxQiurztbtoq4htPp+P3/3ud/Ts2ZMf/OAHKIrCuHHjuO22\n21iwYAHz5s1DVVUWL16MyWQKap+VlfE3HS0ryybnHeHK/v0CqsdD6swrqKrpfCvhaDrnUGrzvM0p\nJI0aTeO2rRxYv6VD0+gjXbR+3m0lYJLMiC6xFx+tlxnUsX/oOqMJQ1q6NACIM4GRmRA2AIDWqWau\nTUdwV1UF6rFEfOnVqxcvvfQSABs3bjzlNnPmzGHOnDndGZYQYeEqK6Nh3SeYevbCdvZ4rcOJSenT\nLqV521Zq3nmLXjGUzMQiuYUpusRe3NoNyNzBkRlobc/sqa3F53KFOiwRodzV1aDTYUhJDel+jy2e\nKevNCCFiX/Xr/wVVJePK2TIaHSaW/HzMAwfRvL0I56FDWocj2iD/AkSnqaqKfU8x+pRUjJlZHX59\noKNZZWWoQxMRylNTgyE1rUtzu0/F3wRAkhkhRKxzHjxA4+aNJPTth3X0GK3DiWnpMy4DoPa9dzSO\nRLRFkhnRae7KSrz19Vjy8ztVHGfM8nc0k7qZeKB6vXjqajFmhK5exs8c6GgmyYwQIrZVr2wdlcm8\n6uqYK0yPNEkjz8KU24OGjesDNZ8i8kgyIzot0JK5g/UyfsZsf0czSWbigaeuDlQ15PUyAHqrFUN6\nhozMCCFimmP/fpq2fo554CASh4/QOpyYp+h0pE2fAV4vdave1zoccRqSzIhOs+85msx0ol4GwORf\na0ammcWFQPF/WuiTGWitm/E2NLQmTUIIEYOq/vsKgIzKdCPb+HPQp6ZS99EavC3NWocjTkGSGdFp\njuJilARz6zofnWDMaq2zkWlm8cF9NJkJxzQzOH6q2f6w7F8IIbRkL95Ny5dfYBl6BolDz9A6nLih\nMxpJu/gSVKeD+jWrtQ5HnIIkM6JTPI0NuMqOYBk0qNPF3DqzGX1KCm5ZODMueKr9bZnDk8wcawIg\ni2cKIWKLqqpUvXZsVEZ0r5TzpqCzWKhd9T4+t3RgjTSSzIhOcezZA4BlUOemmPmZsnNwV1ehejyh\nCEtEMHdt6BfMPJ50NBNCxCr71zux795F0sizsAwcpHU4cUefmEjK+RfgbWigYf06rcMR3yLJjOiU\nY/UyXVtIypiVBaqKu7oqFGGJCBYYmckIT82MIS0NvdWG88CBsOxfCCG0cPyoTMYVV2kcTfxKu3gq\nisFA7Xvvovp8WocjjiPJjOgUe3Ex6PWY+w/o0n6M/iYAMtUs5rlratCZzegsiWHZv6IomHr0wF1V\nKSN9QoiY0by9CEfJXqxjCzD3y9M6nLhlSE3DNmEi7vIymrZt1ToccRxJZkSH+ZxOHN/sx9y3H7qE\nhC7tS9ozxw9PTTWG9PSwduAx5uS0jvRVSnIshIh+qs9H9X9fBUUhY5aMymgtffoMUBRq330LVVW1\nDkccJcmM6DDHvhLwertcLwPHt2eWL5+xzOew42tpCVvxv58pJxcAV7kkx0KI6Ne05XOcB0qxjZtA\nQq9eWocT90y5PUgaNRpHSQn23bu0DkccJcmM6DD7nmIAzF2slwEwZrWOzMg0s9jmXzk5XMX/fsZA\nMlMW1uMIIUS4qT4f1StfA52OjFlXah2OOCp92gwA6td8qHEkwk+SGdFh9uKjxf8hGJnRJyWhS0qS\naWYxLrBgZnp4iv/9/CMzbklmhBBRrnHjBlxHDpM8aTKmnBytwxFHmQcOwpTbg6atW2QRzQghyYzo\nENXnw7F3D8acXAzJySHZpyk7B3dlpXQHiWHu6qMjM2FaMNPPmJ0FioKrTJIZIUT0Uj0eql//L4rB\nQMbMK7QORxxHURSSJ05C9Xho3LxZ63AEksyIDnIePIDP4cCS3/VRGT9jdjZ4vXiOrkMiYk9gZCYt\nvCMzOqMJQ0aG1MwIIaJa/bpPcFdWkHLe+WG/CSQ6zjZhIigKDes+0ToUgSQzooP89TKWQV2vl/GT\nupnY5/YnM91wUTbl5OKtr8Nrt4f9WEIIEWo+t4uaN15HMRpJv/RyrcMRp2BMTyfxzGE49u6RGs0I\nIMmM6BBHcWgWyzyev6OZ1M3ELk9NDSgKhtS0sB/LP7fcLaMzQogoVL/2Izy1NaReeBGG1FStwxGn\nkTxxEgAN6z7VOBIhyYwImqqqtBTvRp+cHFgfJhT8+3JLMhOzPDXV6JNT0BmNYT+WdDQTQkQrn9NJ\nzVtvoCSYSZt+qdbhiDZYR41BZzbTsH6d1PxqTJIZETRPdRXeujos+YNDuvCh0b/WTEVlyPYpIofq\n8+GuqcGYEd56GT/paCaEiFZ1qz/A29BA2tSpGGyhabIjwkOXkIC1YByemmrsu77WOpy4JsmMCJq9\n2F8vE7rifwC9zYaSYJZpZjHK29AAXm/Yi//9TLkyMiOEiD5eu52ad95Cl5hI2iXTtQ5HBEGmmkUG\nSWZE0OxhqJeB1jaHpuxs3JUVqKoa0n0L7fmL/8O9YKafIT0DxWCQjmZCiKhSt+p9fM3NpE2bgT4x\nSetwRBAs+YMxZmXRuOUzfA6H1uHELUlmRNDse3ajJCSQ0KdvyPdtzM5Gdbnw1teHfN9CW55u7GQG\noOh0GLNzcJeXSXIshIgK3qYmat9/F73VRtpFU7UORwRJURSSz5mE6nTS+PlnWocTtySZEUHxNjXh\nOnwYy4CBKHp9yPfvb88sU81ij6emdf0gQzeNzEBr3YzPbm+d4iaEEBGu9v138dntpF96GTqzWetw\nRAckn+OfaiZrzmhFkhkRFP/6MuYQ18v4mQJNAGStmVjT3dPMAIxH2zNL3YwQItJ5GhqoXfU++pRU\nUqZcqHU4ooOMWVlYBg/Bvutr3FXSyEgLksyIoAQWywxxvYyftGeOXZ5q/8hM9zQAgGNNAKSjmRAi\n0tW8+Tqqy0XGzMvRmUxahyM6IXniZAAa1q/TOJL4JMmMCIpjXwkoCpYBA8Ky/0B75koZmYk17ppq\nFIMBvc3Wbcc0BdaakeRYCBG5XBUV1H20GmN2Dinnnq91OKKTbAUFKCZT65ozUqvZ7SSZEUFxV5Rj\nSEtHZ7aEZf+G1NTWDlQyzSzmeGqqMWRkhHRtovbIwpnxp6ioiAULFgBQWlrKvHnzmD9/Pvfdd19g\nmxUrVnD11Vdz7bXXsmbNGo0iFeKY6v++Al4vmVddjWIwaB2O6CSd2YJ1zFjcFeU49uzROpy4I8mM\naJfP6cRTW4vpaB1COLR2oMrGXVEudzViiM/lwtvY2K31MtC6dpHOYpFpZnFi2bJlLFmyBLfbDcDv\nf/97Fi9ezHPPPYfP52PVqlVUVVVRWFjI8uXLWbZsGY888khgeyG04Ni/n8ZNG0nI6491bIHW4Ygu\n8k81q1/3scaRxB9JZkS7/FO//HUt4WLMzsFnt+NragrrcUT38dR2fyczaG2XaczJxV1Rgerzdeux\nRffr168fTzzxRODxV199RUFB65fD8847j3Xr1rF9+3bGjh2LwWDAarWSl5fHrl27tApZCKpe+Q8A\nWVfPQdHJ17Folzj0DAzp6TR9thmfy6V1OHFF/vWIdvnrDvx1LeFi8rdnlrqZmHGsLXPwxf8Oj4Ov\nqnd1eYTOlJOL6vHgqa7u0n5E5Js6dSr641rGH/+7k5SURFNTE83NzdiOq9tKTEyksbGxW+MUwq/5\nqy9p2fkVicOGk3jGmVqHI0JA0elInjARn91O09YtWocTV2SCpmiXv8OYv6g6XI7vaGYZMDCsxxLd\nw13tb8scfDLz4q5X+ax8G78afzu5SZ1PoP0dzVzlZRizsjq9HxF9dMfd5W5ubiY5ORmr1UrTcaO+\n/ueDkZXVfc0rIomcd3ioPh+HVr4CQP7NN2KNgPdZPuvQSLrsEmrefhPHZxsYODNyFz+Ntc9bkhnR\nLv9Clt0xzQxkrZlY4jm6xkww08x8qo/1hzeTaEgE4OuaPV1KZgJrzZSVkTR8RKf3I6LPmWeeyebN\nmzn77LNZu3YtEyZMYMSIETz22GO4XC6cTiclJSXk5we3blZlZfyN4GRl2eS8w6Rh4waaS/ZhG38O\ndlsmdo3fZ/msQyghGfOAgdRtK+JIcSmG1LTQ7j8EovXzbisBk2RGtMtdXg6KEva72/5kySVrzcQM\n99FpZsaM9pOZWkcdL+x6hf7J/QD4unY3U/pM6vSxTdLRLG7deeed/OpXv8LtdjNw4ECmT5+Ooigs\nWLCAefPmoaoqixcvxiRreohupno8VL/2Cuj1ZF45W+twRBgkT5yEo2QvDevXkz7jUq3DiQvtJjM+\nn48lS5awb98+dDod9913HyaTibvuugudTkd+fj5Lly4FWtteLl++HKPRyMKFC5kyZUq44xfdwF1Z\n0dqW2RjeC78xPQP0etyVsoJurAiMzKS1P83sSHNrEjssYwhN7iaKa0vw+rzodfp2Xnlq/mRGOprF\nh169evHSSy8BkJeXR2Fh4UnbzJkzhzlz5nR3aEIE1H20GndVJakXT5XprzHKdvZ4Kl96gYZ1n5A2\nfUa3LksQr9pNZj788EMUReHFF19k06ZNPProo4G7WgUFBSxdupRVq1YxatQoCgsLee2113A4HMyd\nO5dJkyZhNBq74zxEmPjbMndHgaKi12PMyAzU6Ijo566pRme1oktIaHfbspbW6YW5STkMTR/Mx4fW\n803jAQak5HXq2DqzGX1qqozMCCEigtdup+aN19GZzaRfdrnW4Ygw0SclkTRqNE2fbca5fx/m/uFZ\nbFwc0243s4svvpjf/OY3ABw+fJiUlBR27NghbS/jhL9+JdydzPyM2dl4Gxvx2u3dcjwRPqqq4qmp\nCXqNGf/ITI+kHEZknsnY7LMw6Lo2E9aUk4unpkbaZAohNFf7/rt4mxpJm34pBltwzSdEdDq25syn\nGkcSH4JqzazT6bjrrru4//77mTlzprS9jCPdVfzvZ/J3NJP2zFHP19SE6nIF3Za5rLkCvaIny5LB\nsIwhfHf4dfS19e5SDKacXFBV+X0SQmjKU19H7fvvok9OJm3qNK3DEWGWNGw4+pQUGjdtwCeL84Zd\n0Lc9H3jgAaqrq7nmmmtwOp2B57va9jLW2sMFK1rO29lcB0Bmfn8yQhBze+ft7t+XOsDiaCAzSt6j\n9kTLZx1qVhwAJPfqEdR7MKHfKIbaB5CbkxqyGFwD+1G/Fiz2ejKyzgjZftsSr5+3EOL0qt98HdXp\nJGPOd4Kadiuim6LXkzz+HGrff5fm7UXYxhZoHVJMazeZWblyJeXl5dxyyy0kJCSg0+kYPnw4mzZt\nYty4cV1uexmN7eG6Kpra4tWWlAJgNyd3OuZmhxuzSU9uTkq7+3AmpgBQvecb1MHR3043mj7rUMrK\nslG55wAA7sTg3oNzs1qH5UP5frmSWhOjqt378A0aFrL9nk60ft6SgAkRPq7yMurXfoQxJ5eUyedp\nHY7oJskTJ1H7/rs0rP9UkpkwazeZueSSS7j77ruZP38+Ho+HJUuWMGDAAJYsWSJtL+OAu8Lfljmz\n0/tYveUQH2w5yB9+eC7ttYMwSXvmmOGu8S+YGVzNTDgcWzhTfp+EENqoeu0V8HrJnH01ikFWxIgX\nCb37kNC3H81fbMfT0IAhyEV6Rce1+6/KYrHw+OOPn/S8tL2MD66KcgzpXWvLPHNiHmMGZ5GTnkRN\ndVOb2xoys0BRZOHMGHBswczgambCwZiZBTqddDQTQmjCXlJC02ebMfcfgHWM3J2PN8kTJ1H50gs0\nblwvtVJhFFQDABGffE4n3ro6TCHoZFbf5OTF977G6/O1uZ3OaMSQli4F2zHAXd26YKahCyMzX1V/\nzT+/KKTOWd+p1ysGA8bMLFlrRgjR7VRVpeqVFQBkXvP/ZL2ROGQbPwH0ehqkq1lYSTIjTisUbZk/\n31WJ3enhcHULiqLg9rSdzLQeLxtPbS2+4xpNiOjjqakGvR5DSkqn91HWXMG2yi/YVbOn0/sw5eS0\ntvtubu70PoQQoqNavvoC+66vSRoxksQhQ7UOR2jAYEsmacRInAdKcR44oHU4MUuSGXFarorWu9mm\nnM4lMx6vjw1flbHszR1cNLY3100fitnU/nxh/0iQu6qyU8cVkcFTW4MhLQ1F1/afGVVVeW3PW2yp\n2H7Sz4amtzYR+bq2uNNxGHOkbkYI0b1Un4/Kl/8DikLmbJl+H8/8a840rPtE40hilyQz4rS6OjJj\n0Ov4wewR/GB2x7qS+de0kbqZ6OXzePDU1QVV/N/gamJV6Ud8Vr7tpJ/1TMrFZrKyq6b4hPWtOsJ0\nNJmRqWZCiO7SuHEDroMHSJ4wkYQ+fbQOR2jIOvIsdFYrDRvWo3o8WocTkySZEaflv5PdlWlmADpF\nQVVVVq7dy5vr9re7vTFLOppFO1d1DagqhrT2i//Lmls/5x6JJy/MqigKQ9PyqXc1cqS5c78Pxzqa\nSTIjhAg/n9tN1X9fQTEYyLjyKq3DERpTDAaSx43H29hA81dfah1OTJJkRpxWV9oy79xfw8pP9lHf\n1Fr3oigKLXY3manmdl8bmGYmIzNRy3l0iqAxo/2RmSMtrUlKbtKpk+YhXZxqZjw6TVJGZoQQ3aF+\nzYd4qqtJveAijBmdX9ZAxA6ZahZe0vBcnFZX2jKn2hJoaHHR0OImxdq62vHcaUODWlAwMM1MOppF\nLWdlFRBcW+by5tbP+XTJzIiMM7ht1M0MTMnrVCyG1DQUk0lqZoQQYedtaaH6rTfQWSykX3a51uGI\nCJHQLw9Tz540F23D29SE3mrVOqSYIiMz4pSOtWXO7dTre2QkseCSIfTJ7vg/WF1CAvqUFBmZiWKu\nKv8aM0GMzDSXo6CQk5h1yp9bTUmckT4Yk75zax0pOh2mnBxc5WWdrrsRQohg1L73Dr6mJtJnXCZf\nWEWAoigkT5yM6vHQuHmT1uHEHElmxCkdK/4/uY6hPaf7wljT4OCF/+3m46LD7e7DlJ2Du7pKiuWi\nlLMy+GlmF/SZzBUDZ2DSG8MWjzEnF9XpxFNXF7ZjCCHim6eujtr/vYc+JZXUi6ZqHY6IMMkTJoKi\n0LBeppqFmiQz4pS60pb5d899zourTq5vMBp0pCUn0DfH1u4+jFnZoKq4q6o6fHyhvcA0syAaAJyV\nNZyp/aaENR7paCaECLfq1/+L6nKRccWV6BIStA5HRBhDaiqJw4bjKCnBdaT9m7oieJLMiFNyd6GT\n2aIrhjOkb+pJz9sSTcwY349+uUEkM1I3E9WcVVXoLBb0iYlahwIcS2ako5kQIhxcRw5T/8lajLm5\npEw6V+twRIRKnjgJgPp1n2ocSWyRZEackqsLa8ykJ5sZM/jU9Q/B8icz0p45Ojkrq4Kql+moFncL\nbq+7w68LdDQrk2RGCBF61W+sBJ+PzNlzUPR6rcMREco6agw6i4XGDetRfT6tw4kZksyIUzrWljn4\npMTp8gZaMZ/O19/U8udXtrP7QNu1C9KeOXp5W1rwtrRgDKKTWUesPbien398Hztqdnf4tTIyI4QI\nF29LC01bPseU2wPr6DFahyMimM5kwjp6DJ7aGhz792sdTsyQZEac0rG2zMEXZe8va+CX/9zIxh2n\nH02xJhoZf2YOuRltTz/yL5zplpGZqOOprQGC62TWET2tuaio7OrEejN6qxWd1SrtmYUQIde0dQuq\nx4Nt/AQURdE6HBHhrKPHAtC8bYvGkcQOSWbESTrblnlI3zQe+v5ERgw4/ZfY3llWxp2RQ3Ji2212\n9UlJrV8+pWYm6rir/W2Z2x+ZWfblc7yzb1VQ+81L7oNJb+Lrms4tnmnKycVdVSkd8oQQIdW4aQMA\ntnETNI5ERIPEM4ehmEw0bZVkJlQkmREn8Y+GGDvRycySYCDRHJq1WE1Z2bgrK2VeaZTx1LQmM8Z2\nRmZa3Ha2VmynpP6boPZr0BkYnDqA8pZKah0db7FsyskBrxd3tXTIE0KEhqexgZadO0jI69+p7p8i\n/ugSEkgcNhzXkcO4yo5oHU5MkGRGnMRfdG/qwBozW3dXcrCiKaht39tUyn3PbMbubPsOuTE7G7ze\nwJdjER08NUenmbWzxkxZS+uoW25S8L9nQ9LzATo1OmOUuhkhRIg1fbYZfD6Sx43XOhQRRayjWmur\nmrZu1TiS2CDJjDhJZ9oyl9faWfbmDjze9kdRBvZMYf7UwRgNbf/6+Y/vkiYAUcUdGJlpe5pZWXPr\n71mPpOB/z4am5ZOakIJH9XY4rsBaM2VSNyOECI3GTRtBUbCeLcmMCJ71rFGgKDRJ3UxIhGY+kIgp\ngZGZDgyZTx/fl+nj+wa17aDeKUFtZzphrZlhQccitOWprgZFwZCa1uZ2R44mM7kdSGZ6JOVw/8Rf\ndKrIVjqaCSFCyV1djb14N5bBQzCmtf33Tojj6a1WLIOHYN+9C09dHYbUk9fmE8GTkRlxEndFReuX\n0cyurRXTVdLRLPqoXi+O0m+w9O6FYmj7XklZ89FpZonBTzNTFKXT3YICaxdJMiOECIHGzRsBsI2X\nwn/RcdbRY0BVaSrapnUoUU+SGXESV3k5hoyMoNoy1zY6+dt/v2TvofoOHePPr2znoRfbnisq08yi\nj/PQQVSnk+ShQ9vddnb+TG4aPp9Eo6UbImstujSkpwemUYrY5vF4uP3227n22muZP38++/bto7S0\nlHnz5jF//nzuu+8+rUMUUa5x00bQ67GNPVvrUEQUso4aDSBdzUJAppmJE/icTrz1dSSeEdy0LrNJ\nz5C+qdQ3uzp0nGnj+pKV2vaXWL3Nhs5sloUzo4hjT2thvm3okHa37ZGU06F6mVAw5fSgZedX+JxO\ndAkJ3Xps0b0++ugjfD4fL730EuvWreOxxx7D7XazePFiCgoKWLp0KatWreLiiy/WOlQRhVxlR3CW\nfnjoqH4AACAASURBVEPSiJHorVatwxFRyJiZRUKfvti/3oHXbkdv6Z4be7FIRmbECTraltmSYODC\nMb0ZM7hjU9IG90klzdb2l0lFUTBmZeOurEBV1Q7tX2jDvncPEFwyowVjbuvvtUxdjH15eXl4vV5U\nVaWxsRGDwcCOHTsoKCgA4LzzzmP9+vUaRymiVcNGWVumq+S63jrVTPV4aPnyC61DiWqSzIgT+FdI\nNwXRySyYzmXtae+PmTE7G9Xlwlvf8XVFRPez792DLikJS6+eYT1OraOO1Qc+4WDj4Q69TpoAxI+k\npCQOHjzI9OnTueeee1iwYMEJf2+SkpJobGzUMEIRrVRVpXHTRhSjEevo0VqHExXcHi8u97EulH96\neTu7Dxy7rj/zztd8WXJsGYYDFU20ONzdGqMWrKP9LZplqllXyDQzcYLAyEwQa8y8sKqYw5VN/GD2\nCGyJpg4dp6LOzmMrihg5IIO5F+efdrvj62ba644ltOWpq8VTVUXSyLM6XaQfrINNh3m5+HWm9buQ\n3rbgE6dAMlMmyUyse+aZZzj33HP56U9/Snl5OQsWLMDtPvblqLm5meTk5KD2lZVlC1eYEU3O+9Sa\n9pbgLi8jY9I55PQJvoFJJAv1Z11VZ0enU0hPNgPw0HOfMWZINhed3dr1dNigTBSDIXBcp8dHXp+0\nwOM/vLiVGy47k359Wh//54PdTBrZk55ZrVP6vD4Vva7r1xmtf8fVzDMpy86m5cvtZKSag6pVDgWt\nzzvUJJkRJ+hIW+Z5F+fz1b4arJaO/+NLsybwg6uG0yMjsc3tAu2ZKypgcGROXRKt/FPMLINOn5yG\nSn7qAHSKjq9ri5nF9KBfJwtnxo+UlBQMRzvq2Ww2PB4PZ555Jps2bWLcuHGsXbuWCROCmyJUWRl/\nIzhZWTY579OofO8DAExnFcTEexSKz/pwVTMer4++Oa1fkl9esxejQccVk/sDcGbfVBx2V+A4F41q\nvQnlf3zr5Wee8Hj0oEySjLrA4zc/KeHMvqkYaR1dveepjdw6axi9sjpfrxQpv+OWkaOoW/U+pZ9+\nRtKw4WE/XqScd0e1lYBJMiNO4C4vD7ots0Gv46xBmZ06jtGgo3cQf4SkPXP0cOzdC4B54KB2t334\nsydIM6dw0/D5nTqW2WCmf3JfSuq/ocXdQqKx7aTYz5iRAXo9bklmYt4NN9zAL37xC6677jo8Hg93\n3HEHw4YNY8mSJbjdbgYOHMj06cEnwkIAqD4fjZs2obNYSBoxQutwNFPb6KSh2UW/3NYvmLsO1FFy\nuJ6bLmtNSsYMzqK20RHYftwZHWv2MvXsPic8vuu6MaTbWkd5VFUlOcl0QhMhj9eHQR+dlRPW0WOo\nW/U+TVu3dEsyE4skmREncFVUBNWWed+RBvJybV2eTuTzqfhU9bR/hKQ9c/Sw790DOh3mvP5tbufy\nutjfUIpB1/Z27Rmans/e+v3srt3LqOzgvlQoej2mrGxcZWWoqhr26XBCO4mJiTz++OMnPV9YWKhB\nNCJW2PcU46mtIXniZHTGjk2vjnYOlwezqfVrY2l5I29v+Ia7548F4KyBGWSlmgPbDuiZDAQ3jTMY\nmSnHEhdFUbjj2mO1SmuLDrPzm1punRWdi2tbBuWjs1pp2raF7HnzUXTRmZRpSd4xEeBzOPDW17Vb\n/N/icPPUWzv597u7unS8DV+V8YPH1vLFcUV/32ZITUUxGmVkJsL53C6c3+wnoU/fdlsel7dUoqJ2\nuS3z0PTW6Ww7a4s79Dpjbi6+lhZ8TU1dOr4QIv40borPhTLLa1v41bJNgSYaw/qnM3lkj8Dj9GQz\nw/tnaBLb4apmZk3K0+TYoaDo9VhHjsJbV4dj/36tw4lKksyI/8/eeQbGUV1v/5nZ3tV777KKJUuy\nZRtsgzEY08EEY3pLCCEhOBAIEFpCCOQl5E9CQg9gA7apwXQbMO5VXbIlq/dV39X2MvN+kCUXSVuk\nnd2VdH+f7N07956rmZ2Zc+85zxnD2juy+yFw4sxIxQL86Y6FuO585+FEjshNDsYLv1qK/NTJQ9oo\nmoYgLByW7i6wzPTV0wjcYG5pAWuzQeJCiFmXfsQxjZimMxOviMWahAuwJNK9gnWj+WAkb4ZAILgD\na7NBd+QweAolpBmZvjaHUxiGxQubS2G2jCiQhQVIkBkfCL3JBmAkzPzc3Ci/2N1etzIVkcEyAIDZ\nYsfR2pkXyTGqaqYvI6pmU4E4M4Qx3JFlpigKEtH0ohSlYgGkYud9iOPjwVossHR3TWs8AneMJv+L\nU5w7M936kQdNpGx6KkA8modLki5EvDLWeePTICIABAJhKhiO18CuG4a8sAgUj+drczzO7vJODGhH\n8lxomgJFU2js1AAYeebffknmlAR/vMl7O+pQVt/nazPcRjovC5RQSCSapwhxZghjuFIws7Z1EAdr\n1LDa7JO2cRetweKw3owoPgEAYG5p9tiYBM9iqj+pZJbsXMms20M7M1NlVJ7ZqiahiwQCwXWGD46E\nmClnaaHM+g4NDh8/tavx27XzkZkQ5EOL3OfSJQm4+aKMsf8zM6QwJy0SQZqVDUtXJ1m4nQLEmSGM\nMSbL7KDGDMOOJNv1aUyTtnGHt746hkdePTC2dT0RownlJuLM+CUsy8LYcAL8wEDwg5w/+G7LWo9H\nFt4PhWDqkprTgRTOJBAI7sJYLNCVHgU/KBji5GRfm+MRDtao8cmuxrH/X740EcVZEWP/pz1Qx8Xb\nhAVIIOCPvNq2qofx100lYJiZ4dDI80YLaJb62JKZB1EzI4zhiixzZnwgMuM9V7zy+pWpuO3iDIdx\nt6KYWICiSGKcn2Lt64Vdqx0JvXAhflrAEyBaHukFyyaGp1KBEolJ4UwCgeAy+soKMCYTVCvOnzVq\nU5nxgfj+aDtM5pHFxGCV2MkRM4ua5kFcUBgzY5wy+fw8qCkKurISBF28xtfmzChmxy+S4BFclWX2\nJBIR3+kLMC0SQRgVDXNrCxEB8ENOhZhNTxBiujgKVTwdiqIgDA+HtUdNricCgeASw4cOAAAUCxf5\n2JLpceR4z1hejFImxB9uXADxNPNf/ZXVi+LG6tuwLIuKhj6XnxO+gCeXQ5KWDlNjA2xDQ742Z0ZB\nnBkCAOeyzAzL4sWt5dhZ2uHxsa02O3oGDQ7biOMTiAiAnzKW/O9CvgwXtA134C+HXsT3bbtcPkYY\nEQnWaoVtcJBDywgEwmzAbjRCX1EOYUQkRLFxvjZnWnQNGPDut6fKKviDGpk32FXeiY92NsBi8+8F\nLHn+AoBloSsv87UpMwrizBAAnMqXmSz5nwJw8aI4TrZrH3ntIN7f4bhWiCghAQBgJqFmfoep4QQo\ngQDiON885FUiJTp0XTjWX+fyMQIiz0wgEFxEX1YC1mqFYlHxjHz5Hxw2j/37kuJ43LAqzYfW+Ia8\nlBD8Zm0uRAL/VqGT540UAyWqZu5BnBkCAMDaM6JgIgydxJmhKGTEB2LZ/CiPj/3Xu4vx22vnO2wj\nPqloRkQA/AvGZIS5vR3ihERQfOehCha71eM2KIUKRMki0KBpgtXF/oURo4pmxJkhEAiO0Z5UMZuJ\nIWY2O4O/vncUVU0jxalpmkJogMTHVnkflVyEENXIvA0mG55/vwRDpzl5/oIgJBSi2DgYj9fAbjT6\n2pwZA3FmCABck2XmCp4LyZRjIgDEmfErTE1NAMtC7GK+zHNHXsJTB573uB0ZQamwMjY0aJpdak8U\nzQgEgivYh4dhOFYNUXzC2H1jJsHn0bh9TSboGbijxBV1bUOICZUjQCHytSkTIs9fANZmg6Gq0tem\nzBiIM0MAcFrBzAmcGZ3Rit//Zx+27WvmZGyWZdEzZITaQd4MEQHwT4z1I+GBkhTn+TJ2xo4eQy9k\nfKnH7cgIGhm/drDepfaCk7lhlm5Sa4ZAIEzO8NHDgN0+o3Zl1IMG/OuTSthPPivT4wIxb4bVi+GS\nvNQQrPfjUDt5/qhEMwk1cxXizBAAnNyZoSgIJpBllor52HBdHvJSQjgZu2fQiOfeK0HZCcdVe8dE\nALqICIC/MJb8n+S87kKvsQ8My3BSLDMlIAk8ige1vsd5YwA8qRQ8pZKEmREIBIcMHzoIUBQURTPH\nmQkNkMBmZ9DcPexrU/yeioZ+/PvTSr9SORPGxIIfEgJ9ZTlY2+Q1+AinmJ16fAS3sfSoIQgOmTDv\ngaYoRAR5fjV9lPAgKV741VKn7UQJCcC+PTC3NEMUHc2ZPQTXYBkGpoZ6CMLCwVcqnbbvOuloRMgm\nL8o6VUQ8If605BGoRAqXjxGGR8BYfwKM1epVOXICgTAzsA4MwHiiDpLUNAhcKAjsSzr79NDqLciI\nDwRNUbhvbe6MFCvwNpWN/VhVFOtXfyuKoiDPW4ChHd/BUHscsqxsX5vk95CdGcJJWWYNBGETv2Qy\nfrJiQUQA/AtLVxcYo9Hl+jLdo86M1PPODAC3HBkAEIRHACwLa28vJ/YQCISZzfDhgwDLzogQM53R\nilc/r4bxZAFMf3o592duWJWG1JgAX5sxDhJq5h7EmSE4lWV+8q1DeGELt5rnRrMNx1sGz5CQPBtR\nbBxA0zA1N3FqC8E1jA0j+TLiFNecGb1NDwoUIjkIM5sKo8m8JNSMQCBMxPChgwBNQ1FQ5GtTnJIW\nG4Dfr8+HZJYWwOQaO8Ngyw8n0NSl9bUpAEbyUGm5HLqyEpIn7ALEmSGMKZlNVjDz0ZsKsW4ltwUR\ny+v78MmuRvQOTS5FSAuFEEZGwdzWSn7cfoCpfiRfxtWdmbWpl+PF5X9GkDiQS7NcRhhBas0QCISJ\nsai7YW5phnReFngK93Z9vcXeyi58uqtx7P+RwTIfWjOzae4aRle/AWGB/iFbTfF4kOfmwT40BBOp\nr+cU4swQxmrMCCZxZkRCHqJDuL1JFmdF4JGbCpAW63i7V5yQSEQA/ARjQz1oiQTCKNfzlwQ8gd+E\nPwiIPDOBQJiE4UMjtWWUC4t9bMnk5CQFo7FLi2GDxdemzHiSo1W4b20uZGL/yZ8cDTXTl5FQM2cQ\nZ4bgUJbZbLX7lcqHOD4eAEiomY+xDw/Dqu6GOCkZlAt1gryFnbGjVduOHoPzPBhBaBhAUbCqiTwz\ngUA4BcuyGD54AJRAANnJF0p/wmYfiUxQyoT43XV5UEiFPrZodjC60NavMeHrgy0+tgaQzssCJRSS\nvBkX8J+3EILPcCTLvPn7E7jvpT3Q6LivlNs9YMDeyq4xbfyJEJ0UATATEQCfMirJ7GqImbdo0rbi\nuSMvYVfHfqdtaYEAguAQsjNDIBDOwNzWCkt3F2S588GT+EfY0Sg1zQN4dlMJDCYi2csV73x7HBQo\nny/k0iIRpFnZsHR1wtJNolEc4TBTzGaz4ZFHHkFHRwesVivuvvtupKSk4OGHHwZN00hNTcUTTzwB\nANi6dSu2bNkCgUCAu+++GytWrPCG/QQP4EiW+eaL0nH50kQoZNyv/Oyv6oZ60ID5KSGQSyb2s8dE\nAIgz41PG6sv4mTMTr4gBn+KhYajZpfaC8HAYqqtgNxr97qWFQCD4htEQM39UMcuMD0RucjD0Jiuk\nYpLszwW/uSYXfJ5/rPXL8xZAX1oCXWkJgi6+xNfm+C0Ofwmff/45AgMD8fzzz0Or1eKKK65ARkYG\nNmzYgMLCQjzxxBPYsWMH8vLysHHjRnz66acwmUy4/vrrsXTpUghI7Qa/hzEZYddoIJpEx5yiKAQq\nRF6x5aplSU7b0EIhhFHRIyIAdjsoHs8LlhHOxtRQD1CUS8UyAUBt6IVMIIVcwG3ulYAnQKwiBi3D\nbTDZzBDzHV+7wohIGKqrYFWrwUtI4NQ2AoHg/7AMg+FDB0GLxZDlzPe1OWP0a0wIVolBURSuOCfR\n1+bMak53ZEpP9CIhQum196Czkc/Pg5qiiDPjBIeu58UXX4z77rsPAGC328Hj8VBTU4PCwkIAwLJl\ny7Bv3z5UVFSgoKAAfD4fcrkcCQkJqK2t5d56wrSxjCX/j6/9YTTbYLL431a2OD5hRASAbLv6BNZm\ng6m5CcLoGJd3M96ufh+P7X0GDMu9Cl1yQAIYlkGLts1p29E8MRJqRiAQAGC4tg62gX7I8wtAC/0j\nF6VvyIin3zmME+1DvjbFI7Asi15Dv0u5jb6kvl2D97bXQWe0+swGnlwOSVo6TI0NsA3NjvPPBQ6d\nGYlEAqlUCp1Oh/vuuw/333//GTGEMpkMOp0Oer0eitOkC6VSKYaHh7mzmuAxHMkyl9X34bcv7UHZ\niT6v2VPR0Ie9lY6dlFMiAM1esIhwNub2NrAWi8v5MgzLoFvfgzBpKGiK+637ZFUCAKBB41wkQkBq\nzRAIhNPo3bUbAKBY5D8hZiEBEtx9RbbPdgemy6jzsq/zEN6u3ozH9v0FTx54Dt82/zhh+8q+GrxV\n9R6+aPwOh7pL0KJtg9Fm8rLVQHK0Ek/fvhCxYXKvj306YwU0y0t9aoc/4zTgsqurC/feey9uvPFG\nXHLJJfjb3/429p1er4dSqYRcLodOpxv3uSuEhvqnfjvX+Mu8TboRTz8kLRFBZ9l0+QoF1pybDJZl\nIeB7JpzL2bwrvz+ByGCZw3bivCz0vA/QPZ1+83d0xEyw0R06D4zseITlZzuc2+h3Pfp+WBgrEoKi\nvfK3KFJmY19POhLDnI+nmJeMDgDUUL/HbJtt55tAmCuwdjv69+4HT66ANGOeb21hWVQ3DSArMQgU\nRSEz3j/qc02Fqv5jeKXi7bH/ywUy5IflIiNo4vp1TZpWHO0pH/f5xQkX4NKkC7kycxwURUF6UqrZ\nZmfQ0KFBepz3z4M8Lx+9m9+HrrQEAcvP8/r4MwGHzkxfXx/uuOMOPP744yguHtFaz8zMxOHDh1FU\nVIRdu3ahuLgYOTk5ePHFF2GxWGA2m9HY2IjUVNeKLPb2zr0dnNBQhd/Me6hp5MXUKOLeJlfmfcPJ\n4pyO2jHyYICmMXi8zm/+jpPhT+faU/SVVwEArKExk87t9HlX9zUAAAJ5wV77W9yddQcA5/cXlhWB\n4vMx3NruEdtm6vkmDhiBABiOH4NVo4FqxfkTCuJ4E4uNwUc7G9Deq8fqRXE+tcUZLMui3zSALr0a\nOSHjncBEVTzyQ3OQFpiM1MBkREjDHNYbuzTpQpwTvQg9hj6oDb3oMfSix9CHKHnEhO37jANQiZQQ\n0Nyds/98VgUeTSEtNsDrtdIEIaEQxcbBcKyGiNVMgsMz/+qrr0Kr1eLf//43Xn75ZVAUhUcffRR/\n/vOfYbVakZycjNWrV4OiKNx0001Yv349WJbFhg0bIPSTWFOCYyaTZbbaGPQOGRERJAVN+0eRw1GI\nCIBvMTbUg6dQTJhnNRHdhpG8rEiZa+29CUXTEIRHwKruBsuyflPQk0AgeJ/hgwcA+IeKmUjAwwPX\n58Nq4z7PcKr0GwfxXeuPqO47jkHzEPg0H//v3Kcg4J0p/iQXyHBnzk0u90tTNILEgQgSB066ezMK\nwzJ4teJtmO0WXJZ0EQrC53MSznzd+SkICZD47Bkhz18Ac1srDJUVfnF9+hsOnZlHH30Ujz766LjP\nN27cOO6za6+9Ftdee63nLCN4BUuPGoKQ8bLM/VoT/u+jchSkheFn53tPftdgsmJ/tRpBChHy08bX\nvRlFnJAAS3sbLN1dEEXHeM2+uY51oB+2gQHI8vJdvqnzaT7CpaGIlI3Py/IHhOHhsHS0w67Vgq9S\n+docggd57bXX8MMPP8BqtWL9+vUoKiqasLQAgcBYrdCVHoUwOBiSFNciSzwNy7LYfqQdS7IjIJcI\nIJf4pyIsy7L4tP5L/NS+FzbWPhI2FpqD1MBkMPBubRYbY0N6UAp2te/H2zUf4PvWn3BFyhpkBqV5\ndJywQOnYv3uHjAiQCz0Wfu8K8vwC9H/+GXRlJcSZmQD/ENIm+IRRWWbBBMn/EUFSPHf3Eqw9zzXp\nXU9hZ1i09QyDx3P8oiw+WTzT1Ow8yZvgOUwNIyFjkmTXH/YrYpbi8eIHEe6HOzPAKREAomg2uzh0\n6BBKS0uxefNmbNy4EV1dXXj22WexYcMGbNq0CQzDYMeOHb42k+AnGGqqwRiNCDl3KSjad69GQzoz\nNn3n32qwFEXBZDdDJVLi5szr8Ow5f8SdOTdhecwSiHjejcoR8oRYm3o5Hi9+EEXh+WjTdeJfZW9g\nY81WTsZrVQ/jmXePoL5dw0n/kyGMiYEgJBT6inIwVt+pq/krpOLSHOaULPPkK+a0l7dUFVIhbr04\n02k70UlnxtzSDCw9l1ujCGMYG04AACQp/lUsczoIRxXNuruBtHQfW0PwFHv27EFaWhruuece6PV6\nPPjgg/jwww/HlRa44IILfGwpwR/QlRwFAAQvLobZRzZQFIVrVyTDaLb7yALXuSplDQT0FeBzmKfi\nDiGSINyadT1Wxi3D/xq+Rkqg87p1UyEiSIpfr81FcpR3d/EpioIsfwGGtn8LY+1xyLJzvDq+v0N2\nZuYwp2SZx6+Y17UNQWuweNsklxHFxAI0DVNLi69NmVMY6+sBHm/MmfRnGoaasbXuMwyaHGvzC8nO\nzKxkcHAQVVVVeOmll/Dkk0/igQceAMOcyj+QyWSkhAABwIiKma68FDxVABRp3g8x+6GkHcdbBgGM\nKmj5h4NgY2yo7j8+4XcSvsRvHJnTiVVE4968O1EcUcBJ/0IB7wxHxmb3Xk7TmERzaYnXxpwp+N+V\nSPAaFvWIMyMIP3NnhmFZbNvXDJqicP/PvF8Bub1Hh/3V3SjMCENi5MQS37RQCFE0EQHwJozZDHNb\nK8Tx8X5TTM4RLcNt+Kl9HxKUcVgYsWDSdoIIUjhzNhIQEIDk5GTw+XwkJiZCJBJBffKeB5ASAq4w\nV+atqawCo9MhYvWFoGja6/NOTQjGxq9q8HzeuV7Nwzid0+fMMAz2tB7Gh1VfQK3vw18ueAgpwQk+\nscuT2Ow2fNewCyuTzoGIP/IMm+q5ttsZvLmtGgNaEx6+uciTZk4KG5SPbqUShooyhATfM61wyNn2\n2ybOzBzGqh7dmTlT7pCmKPzuujxfmAQAMFvtEAt5TlenRPEJMLe1wdLVObJTQ+AUU0szYLdD7Ea+\njC85VTyz2aEzw5MrQEulY78HwuygoKAAGzduxK233gq1Wg2j0Yji4mIcOnQICxcuHCst4AozUW57\nusxUmfGp0PPDSKFMXmYuAO+f79ggCR6+YQGGBg1eHXeU0XPNsiwq+mrwReO36NR3g0/xsCJmKWiT\naFZcC7va92FL3Wf4tPobXJJ4IS7LPQ8D/VP7m7MsC7mIh1Urkr36t5HmzId27260HSp3uXD12czU\n37YjB4w4M3MYa2/PSVnmEF+bcgbJ0SokRzuPRxXHJ0C7ZzdMLc3EmfECpoZ6AHDrBnpisAEAhSRV\nPHi0d1ccY+RRENICNA41O2xHURSE4REwtbaAZRifJv8SPMeKFStw5MgRrF27FizL4sknn0R0dDQe\ne+yxM0oLEOY2LMtCV1YCWiqFND3Da+NabQz2VHZheV4UaIryen7qRPzUsQ8f1v0PFCgURxZiTcIq\nBEtmbrHOsymKyIfGrMX3bbvxfu3H2N29H3fNuxnBkiC3+6IoCqsKvf/eoSgqgnbvbgx8uQ3Rv7nf\n6+P7K8SZmcNY1N0TyjLXtg5CJOQhLlzhFzfYyRDFJwIgIgDewjjqzLiR/P9547do1rbi78v/DG8H\nT/BoHhJU8agbrIfBaoBUIJ20rSA8HKamRlj7+yAM9U/VNYL7PPDAA+M+m6i0AGHuYm5phm1gAIri\nxV4tlGm22nGwuhtWG4MLi/xjMW5heD5atG24KP48RPiplP50kPAluCx5Nc6NWYxtjd/iQNcRvHD0\n33iw8F4EigOm3G/PoAHfHmrD9Rekgs/jdjFMmpUDSUYm9BXl0FdWQJaTy+l4MwWyBDlHYUxG2LXa\nCZXMjrcO4Z1vasGy3tWLP51Dx9R45X9VMJptk7YRxcYAPB5Mzc3eM2yOwrIsTPX14AcHgx/g2kod\ny7Lo1qsRKgl2uTLzrvJOHKju9lhS5WioWaPGsVCEMCISAGAleTMEwpxiVMVMvqDQq+PKJQI8cH0+\nzsuP8uq4jpAKpLhl3rpZ6cicToBIhZsyf4ab865BamASVCLXcucmY/uRdoQFSryy+EtRFMKuWw9Q\nFHq2vA/WNvk70lyCODNzFEeyzFeck4gnbi0Cz4fhNgIejZykYIc3B1oghCgqCub2NrB2/5eynMlY\ne9Sw64bdqi+jtehgsBndejCqZEIcqe0Fy7IwW6d/TheE5eKWeesQr3S88jmmaNZN8mYIhLmEruQo\nKKEQsqxsr4zX3quDRjci/szn0T5J+O8z9qND1+X1cf2NS9MvwK3zrgdNTe9d54ZVabhoYRxo2juR\nLKLYWKhWnAdrdzeGfvjeK2P6O8SZmaOMJf+H++cKTH5aKJbmREIkdHyjF8UngrVYYOnq9JJlcxNj\n/UiImdiNELNu/cg1Fil1PWxrfkoI7r06B+X1/fjDq/sxPE158Ch5BBZGLIBCKHfYblTRjyiaEQhz\nB0tXJyzdXZBmZYMWibwy5rGWQfz53SMOow64gmVZ7O44gGcOvYg3q96DlSGr+pSHd1NqmgdgtXEv\n1xxyxdWgpTL0b/sMNq2W8/H8HeLMzFEsJ2vMCM6qMdPUpcXR2h4YTDPjJic+We+EhJpxy1jyf5Lr\nzkyXYeQac3Vn5vSwRqVMiN9eOx8KqXckoIUndyhJmBmBMHcYrdehyOemJslErCqMxYPX50Mi8m7K\n8pBZg5fL38Tm2k/Ao3i4OGEl+BQpaTARFrt1Ssftr+rG218fR7/W5GGLxsOTyxF85VVgjEb0f/Yx\n5+P5O8SZmaNMJsus0Vmwp6ILA8Pc/xidseWHE3jzyxqHbUaLN5pamrk3aA5jbKgHJRRCFBPj8jHB\n4kDkhWYjRuE8Jrxn0IDH3jiIo7Uj4Y9psQGIC/eeDj4tFoMfGEh2ZgiEOcRwyVGAx4Msl/t6iDfY\nmQAAIABJREFUaj1DxrF/hwVOLkbCBSU9Ffjzwb/j2EAd5gWl47FFG1AUke/xXYnZgNFmxAtHX8a2\nxm/dzhvOTwvBU7cvRESQd85vwPLzIIyKhmb3Lpha53YBceLMzFEsPWqApsfJMuelhuC+a+cjJtRx\nWI43iAtX4Nxcxy/CoyIAZuLMcIbdoIelswPixCS31H5yQubhrpybEenCzkxogAS3rM6ASnZmqIfZ\nasd72+tQ1zbktt3uIgiPgG1gAIxleqFtBALB/7EO9MPc3ARpWgZ4cm6fd3qTFX/ddBQ7yzo4HWcy\nGJaBnbXj+vSrcc/82xEgcl76YK5isJpgspvxTfP32Fz7CRjW9ZAxsZA/tuNmszOw2rjN5aV4PIRd\nfwPAsuj94D2fijb5GuLMzFGsPWoIgoO9KkXpLouzIpAW61gucUQEIBrmtlYiAsARpsZGgGWnXKDL\nFSiKQlpsAFJiznzIdvTqYTDZEB0qm/YYzm70wvBwgGVH6i8RCIRZzWiImXzB5AV1PYVMLMBjNxci\nNWbq8r/ToSBsPp5a/BDOiS4muzFOCJYEYsOCexAtj8SezoN4awq5RQNaE/6y8Sh2V3AvsiDNnAdZ\n/gIYT9RBd/gQ5+P5K8SZmYPYjRPLMvcOGfHdoVZ09et9ZNnUEMUngLVaYekkIgBcMFpfxp3kf3cY\n0JomlWJOilLirsvmQSYWTGuMTcc+xJP7n3Po0AijR0LojLXHpzUWgUDwf0adGVked86MxWoHw4zc\nc4KUYkSHTH9RZipQFAWl0HthuzMdlUiB+xfcjZSARJT2VuI/5W+5lUcjlwiwqigW5+VHc2jlKUKv\nXQeKz0fvR1vAmM1eGdPfIM7MHGR05flsZ8bOsFAPGdHdb/CFWeMYHDbj/z4sx//2NDlsJyZ5M5xi\nqnc/+d8dth9pw4P/3udUdEI9aJhyuJmNsaPPNAC1oXfSNooFhQBFQbNv75TGIBAIMwP78DCMdbUQ\nJyVDEMhdhfvtR9rw961lMJimllDuLsf667Cv87BXxprtSPgS3Dv/TuSGZCFYHORyrTQAEAp4WJwV\n4bVdMGFYGAIvXA3bwAAGvvnKK2P6G8SZmYNMJsscESTFTRemIz8t1BdmjUMm5mNpTiTOzY102E6c\nkACAODNcwDIMjI0NEEZEchZXft35qfjjLYWQiid/WBjNNjz3XgnUA1NztJMD4gEADZrJHWN+QACk\nWTkwNzfBTHb5CIRZi668DGAYyDlWMVu9KA75qaEQCrhVDTPZzNhc+yn+Vf4GPj7xOQxWo/ODCE4R\n8AS4M/tGrEu/asqOyaFjamz9sd7Dlo0naM0l4KkCMPjNV7D293M+nr9BnJk5yKhi00QFM/0JoYCH\nwowwBCnFjtvFjIoAON7BIbiPpaMDrNnkdojZgbYS7GrfD5PNtS1vZ+dYIuLjz3cW49z5U6uWnaxK\nBAA0DDU7bKdashQAoN23Z0rjEAgE/0dXehQAd/kyo+GsPJrGyoIY8HncvWoNmTX429F/YXfHfkTJ\nIvDbBXdDKpBwNt5cg0fzwKOn5ozaGQZHa3tRkM79AjEtliB07bVgrVb0friF8/H8DeLMzEGsPSNh\nZsLTnBk7w2Dz9ydQ0dDnK7OmzCkRgDYiAuBhjA0nAMDt5P/tDbuwpe5Th22sNjt+KGl3OQTj9J0b\njd49xbEIWRgkfAkaNM0O28ny80FLJNAe2AeW4b7wGYFA8C6MyQRDdRWEUdEQhkc4P8BNLFY7nn77\nCGpbBz3e99n0Gfvx96P/QbdejWXRS/D7ot8gVuGdPI25jisqZzyaxi+vzEZylHfU4xSLFkOclATd\nkUMw1NV6ZUx/gTgzc5CJZJltdhYqmRADWv9KHqts7Mfjbx4aqz8yGaIEIgLABWPJ/8mpbh3XrulG\nkDgQYv7kVbUNJhvq2obw3eE2t/p+77s6/N+H5W7JUNIUjSRVPLRmLQzWyUPVaIEQioWLYB8aguGY\n4xpHBAJh5qGvqgRrs0G+gJsQM6GAh2tWJKFriiGx7mCxW2GymXBJ4ir8LO0Kt/I6CFNn2KLD3478\nE3WDDS4fY7XZsb+a2zpmFE0jdN2NAIDeDzbNqQU5cuXPQUZkmUPOkGUWCXi4uDjeh1ZNTEyoHLet\nyUCME2lecXwCtLt3wdTSBFFsrJesm/2Y6utBS2UQRri+gmmwGjFo0mBecLrDdiq5CHdfke22TQXp\nobh6eZLbMcw3Zl4LGV/qNGRAueQcaH7aCe3ePZBluW8fgUDwX3QloyFm3OXLZCcGc9b36UTJI/BY\n8e+IUpmX6dB1oUPXjdcr38XvC3+DUKnz8/3uN7UwWewoTA+DgM/dPoIkKQnKJUuh3bcXmt27ELB8\nBWdj+RNkZ2aOcUqWOczXprhEoEKExEglBHzHL6BE0czz2DQaWHt7IElOBkW7fqvoNozsokVIubnG\nMuIDxwqTuYNSqHAp9lmclAxBeDh0pUdhN/iHsh+BQJg+rM0GfWU5+MHBEMXGebTvAzXd+N+eJjBe\nLlxIHBnvkxGUinXpV8FgM+KVyrdhtJmcHrN+VRruuSqbU0dmlJCrrwUlEqP/049hN8ysUhtThTgz\ncwxrz8RKZh//1IAv9zd73yAXsdqYMb3+iRDGxJ4UAWj2nlGzHFPjaIiZe/ky3fqRayxSNrnAxLa9\nTfj4pwYYze4VIzudjl4d/vpeCQaHPRsaSVEUlIuXgrVaoTtCZE4JhNmC4XgNGKMR8vwCj8vmpkSr\n0NGrw6CfhWoTuGFJ1EKsiFmKbr0a79R84DSHRiLij11zGr3FrTBpd+EHBCD40stg1w2j//P/cTaO\nP0GcmTnGaPL/2UpmiZFK8NxYffcmO8s68Nt/7kFbj27SNrRAAFF0DMytrWBtU39BJpzCOFpfxk1n\nJkYRhWvmrUGSKmHSNgXpYWBYdlqrVB19eizOCkeAXDjlPiZDuXgpQFHQ7ic1ZwiE2QKXIWYhKgnu\nuSoHwSrHyoxTpby3Gjvbyf3In7g65VJkBKaisu8YSnsqXTqmoqEff3zjIDr6uN0xCbjgQghCwzD0\n4/dzotQAyZmZY0wmy7zAT2rLTERuUjAWpIZCKXP80iqKj4e5tQWWrk6PhxDMRYwN9QBFQZyY5NZx\ncYoYFCRlord3eNI2USEyXLtiekU4F2ZyJy0uCA6GNCMThmM1sKjV43YyCQTCzIJlGOhKS8FTKCBJ\ncU/QxBEn2ocQFiiFysnzaToc7i7Fu8e2QEDzkR+aC5WIhJb5Azyah9uzb8BRdTkWhOW6dExUiBQP\nXp+PmFBu6raNQgsECL3uenT+6//Qu+V9RP/2d14r4ukL/HMpnsAZk4WZ+TNBSrFTRwYgeTOehLFa\nYW5ugig2DrTYsyuNZotn5bNZlsWBmm6XV7o0Zu1YKJwjlKM1Z8juDIEw4zE11MM+rIUsL9+tHEBn\n1LUN4Zl3j8Bq40Y5ak/HAbxTsxkinhD35t1FHBk/QyaQYlnMYpcdhRCVBLFh3Doyo8jm50E6LwuG\n6iroK8q9MqavIM7MHMPS0zMiyxx8SpZ5++E2vP31Mbdrd3ibwWEzdMbJa5KIE0YKIxJnZvqYW1vA\n2mxu58s4Y0Brwu9e3ovtR9yTY3ZEU9cwtu1tht3u/GVCbzXgkb1/xod1nzttK19QCEokhnb/3jkl\ncUkgzEbGQszyPRtidsniBDx+axEnid07Wn/CB7WfQCaQ4r78u5Gk8j/FUcLU0Bmt2Pz9CfQMcicy\nQ1EUQtetB2gavVs+AGN1rabbTIQ4M3MMq3q8LHNmQiBiwxQQC6ZW5dYblNT14vE3D6K+QzNpG2F0\nzIgIQHOz9wybpZhO1peRpHjWmQlSivHMXYuQnRjksT6TopR46vaFiAt3vmIpE0gRLg1Dk7YFdsbx\nDhEtEkFRUAhbfz+Mc6wAGYEwm2BZFsOlR0GLxZBmzvNInxbrqfuHXCLwSJ+no7ca8H3rLgSIVLh/\nwS8Rq4jy+BgE33G8ZRAWGwOxkNtsD1FUNALOWwlrjxpD32/ndCxfQpyZOYTdaIR9WAvBWSFmMaFy\nrCyIgUjov85MTlIwXvz1OchLCZm0zZgIQBsRAZguo8Uy3Un+Z1jGJYUWlVyEyGDHdYPchc8buZVZ\nbXb0DBkdtk1WJcBst6BT77yAmXLpOQAA7T4SakYgzFTMba2w9fVBljsftGD6jgfLsnju/RJ8ssv1\noonuIhNI8eu8u3D/gl8iQjYzSikQRug19OPLpu0On4eFGWG4+aJ0l0Lop0vw5VeClssx8MXnsGmG\nOB/PFxBnZg4xli8zQ2rMnI6AT4+9sDpCnJAA1maDpWv2q3dwBcuyMDbUg6cKAD94cufxbHa27cEz\nh/6O1uH2Cb9v6R5Gv8a5Hv9UsVjtePrtI/hqf7PDdskBCQCAhiHH7QBAkpoGfkgIho8eBmPiznYC\ngcAdutISAJ4LMaMoCvetnY+4MG7zV6LkEQiReG4Xm+AdttZ9hq+atuPH9j0utR8cNnMq1cyTyRBy\n5dVgTCb0ffIxZ+P4EuLMzCGs6hFnRhB2qpp76YlevLClDHVt3HjrxwbqYGM8s0vCsCwaOjRo6Z5c\nJUs0KgLQ3OSRMeciVrUa9qEhSFJS3FI/OawuhdrQi0BRwITf17UN4am3D0Nr4CY3Syjg4b61ubj1\n4kyH7UYloxs1zU77pGh6pOaM2TwWc08gEGYWupKjoPh8yHJyPNanUiZEYcbMWxgkcM8NmWuhFCrw\nyYkvcKy/zmHb/VXdePzNg+ge4LZAs2rZCghjYqHduxvDJ+o5HcsXEGdmDmHpGXVmTt2AU2MCsLIg\nBoEKkcfHaxvuxMtlb+KNqo0AgJahdrxe+S40Zu2U+uvuN+Dtr4+ja2By1apTimYtUxpjrsMyDNSb\n3gEAyPMWuHycWt+D1uEOZAalQSGcWKllVVEs/n7vUiil3G2rhwRInLYJlQQjJSARIZJgl/pULh5R\nNdPsc22VjUAg+A8WtRqWjnZI52WBFju/PzjCarPj3W+Oe3yH2WgzoqSnwqN9EnxHgEiFn+fcAh7N\nw5vV70Ft6J20bVpsAJ6+Y5HHQ6/PhqJphK1bDwBofOW1WReKT5yZOcREssxyiQB5KSEIdeEl0B0Y\nlsHWus/AgsXy6JGXwRP9zSjrrcK3LT9Mqc+oEBn+dOciFM+LmLTNmAgAUTSbEoPbv4Xx+DHI5udB\nUbzY5eMOq8sAAIXheQ7buRIqOF3MFjt2lXdOugNEURTuX/BLXJ682qX+hGFhkKSmwVh7HNb+fk+a\nSiAQOEZX6rlCmRRFIUgpxs6yjmn3BYw8J/d2HsST+5/Hm1WbUOZi4UWC/5OoisP69GtgtBnxasXb\nsNgnfh4Fq8ScLCZPhDQjE8rFS6Grb0Dfpx95ZUxvQZyZOYRFrR4ny8wVh7pL0KhpRl5oDjKD0wAA\nKxIXI0QchD0dB9FvHORkXCICMHXMba3o//Rj8BRKhN9yu8shZizL4rC6FEJagNyQrPH9Wux4b3sd\n2np0njZ5QvZWdaHsRB9MZs+df+WSpQDLkpozBMIMQ1daAlAUZPMdL7S4Ap9H49IlCbhmefK0+6of\nasLzh1/C+8c/hoWx4rKk1cgKcRwiS5hZLIoswKq4FVgesxQC2rHwxIDWhI3f1cJg4va9JeyGGyGO\nisLgt99AV1HG6VjehDgzcwhrT88Zssy9Q0b84bUD+P7oxAnbU8VgNeKz+q8gpAW4JvXSsc/5NA9r\nElfBztrxTfP3U+rbZmdw6Jgaeyu7Jm0zKgJg7vTM6tlcgLFa0PX6q2BtNoTfdgf4SqXLxw5bdeDT\nfOSGZkHMH7/CxLAslFIBalu5cWDP5vwFMfjN2lyEBUo91qe8cCEooXCk5gyHiZoEz9Pf348VK1ag\nqakJra2tWL9+PW688UY89dRTvjaNwDG2oSGYGuohSUsHX+H6Pe1s7AzjsCyAuxxVl+PFkv+gTdeJ\nhREL8ETxg1idcD4ENLcyvQTvc2XKGiyPWeJ0cfDw8R5IRXx4sJ7rhNBiCTJ+/ztQfD6633wd1oEB\nbgf0EsSZmSNMJMscpBThV1dmIz1u4oTtqXKouwTDVh0uSliJIHHgGd8VReQjXBqGA91H0GPom1L/\nR473OCxQNioCQELNXKfv449g6eyA6rzzIc+d79axSqECjy3cgBsy1k74vUTEx2VLE3FBYawnTPUJ\nPIkE8vwFsKrVYzV4CP6PzWbDE088AbFYDAB49tlnsWHDBmzatAkMw2DHjh0+tpDAJZ5SMesdMuE/\nn1U5XERzh+yQTMwPycIDBb/CLfPWIUCk8ki/hJnLRQvjcM3yZM7rzgCALDEBoevWg9Hr0f36K2Dt\njmuuzQSIMzNHMLeOJMQLIyLHPuPRNGLC5IgJnThhe6osj1mCn+fcgpVxy8Z9R1M0Lk26EAKaj06d\n+w8GPo/GPVflYGFm+KRtxPGJAIgIgKvoq6swtOM7CCIiELr2uin1QVEUhLzxif2+2sWwMwy27WvG\nxm89V+xSuYTUnJlpPPfcc7j++usRFhYGlmVRU1ODwsJCAMCyZcuwf/9+H1tI4JKxfJl818VMJiIi\nSIo/3bEI+ameCdEW8YT4ee4tSFTFe6Q/wuxicNjM+Riq5edBXlgE44k69H/+GefjcQ1xZuYI+opy\nAIAsK3vsM65eNCmKwvzQrEm3zPNCs/H0kj8gL8xzMpmnI4yOBng8Is/sAnadDt1vvQHweIi8827Q\nIs8mIm75oR7//LiCMznmyeDRNFiWxbL5k1fN7jMO4NvmH9CsbXWpT2nmPPADAzF8+CAYi3fnQ3Cf\nTz75BMHBwVi6dOnYvY5hmLHvZTIZhocnl3knzGzsej0Mtcchik+AINg15cKzYVgWzMlrRyrmQyp2\nr+Bmq7Yd9UPkOUQ4k269GkPmicMWv9zfjKffPgyDycqpDRRFIfzm2yAIDcXAV19AX13F6XhcQwI0\n5wj6inJQQiEkGRkARhyZh17Zj6QoJe6+ItvJ0Z6FpmjIBdOTIfzuUCs6+vS4bc34hMlREQBLextY\nm20sR4hwJizLQv3uf2HXDCHk6rUQJyR4fIwrz03EkeO9kIm9fw4uX5ro8PteQx8+b/wGF9rPQ4Iy\nzml/FE1DUbwEg19/CX1ZKRQLF3nKVAIHfPLJJ6AoCnv37kVtbS0eeughDA6eytvS6/VQupgbFhrK\nbXFEf2Umz7unugSw2xF+7hK35zHafk95Bz7f1YgN6xcgwg3p3CGjBh9Ufo6dTfsRLg/Bixc/AR7N\nc8sGbzOTz/V08Pa81bpe/L9dLyNGGYGnzv8d+Lwzn40rFyVg7aoMyCXuOc7uMjJvBWQPPYDKhx9F\nz1uvI+8fL0AYFOj0WH+EvOXNASw9PbB0dUKWlw9aMBIKRFEUnrytCANe2M7kAoqiUJQ5ecEycUIi\nzK0tMHd2QBxHtvInQrtvD3QlRyFJTUPg6jWcjCEW8nFObqTzhhxittrBo6lxstAJqjhQoNAw1Oxy\nX6olSzH49ZfQ7NtLnBk/Z9OmTWP/vvnmm/HUU0/h+eefx+HDh1FUVIRdu3ahuLjYpb56e+feDk5o\nqGJGz7tr50g4KJWW7dY8Tp93aqQChWkhGNYawTttV28yrIwNO9v24Jvm72GymxEli8DalMsx0M9t\nQcTpMtPP9VTxxbwpVoTs4EwcVpfiv4c+xpUpZz57xTRg1Jlg1Hm2ltHpnDHvgHCErP0Zeje/j6rn\nXkDMhgdBca1CMEUcOZ7+aTHBo4yFmJ2V2C0VCzyWL2OycffDm4hVRbHITpw8dGBMBKC52TsGzTAs\nPT3oef890BIJIu78+ZRuXtX9x7Gt4ZtJt8u5rmjsCkdre/HAy3vR2Dm+UKuEL0aMPBItw22wMq7J\nYQojoyBOTIKhuhK2Ie+osxE8x0MPPYSXXnoJ69atg81mw+rVrtUaIswsGLMZ+upKCCIiIIqaPNTU\nGTRF4bwFMQiQuxZ++2rF2/is4SvwKB6uS7sKDxfdh/SglCmPT5h9UBSFdelXIVQSjB2tP+H4wIkJ\n23X26fH+9jowDPd5pwErV0GWlw/j8WMY+HIb5+NxAXFm5gD6k1rispxTzozV5nyVyVU6dF14dO9f\nsK/z0JSOZ1kWRpvRY/YAgPikM2MiimbjYO12dL/5GlizCWE33DTlukO7Ow7gm5YfYJzAkdXozPjb\nB6XY+qNvlb+SopR48raFSIudWLEvKSABNsaGtmHXZbzHas4cIMnjM4V3330XiYmJSEhIwMaNG7F5\n82Y888wzLtdSIswsDDVVYC2WKauYHa3tRemJyau2T8a50cVYEbMUTyz+PZbFLPb70DKCbxDzxbgt\naz0oisK7NZsxbBlfg21XeSeClOKxnC0uoSgKEbfeAX5QMPo//wyG48c4H9PTEGdmlsOYjCNJkHHx\nEASeioV8bVs1fvfyXpgs0yvQxLIsttR+CpPdBNUU5CVNNhNeOPoy3qjc5LzxWXy5vxkPv7IfZst4\nWUFhdDQoPp84MxMw8NUXMDXUQ7FwERSLFk+pD73VgJr+WsTIoxApG68sp5KL8PwvF2P1Que5KFwS\nqBAhWCWe9PtkVQIAoMGNJF1F0SJQfD60+0jNGQLBHxkuGVExUyyYmjMjl/Dx2e4maPXuCX3MD83G\ntWlXQCbwXI0rwuwkXhmLy5NWQ281TChCs25lKlYvihsXHs0VPLkckb/4JUBR6Hr9VdiGx0cz+DPE\nmZnl6GtqALt9XIjZPVdm4w83LJi2pvlhdSkaNM2YH5qNrOB0t48X88UQ88U4PngCdYMNbh2bGhOA\n+67NhUg4fvWLFgggPE0EgDCCsbEB/dv+B35QEMJuuHnKK9MlPRWws3YUhk9eVZtH01DKxss1+wKN\n3oLq5vHFwVIDk3Fl8hpku1F5myeXQzY/D5bODpiJ/DeB4FewNhv05WXgBwZBlOBYBGQy0uMC8eRt\nRX5z/yLMTlbGLcMjizYgJ2Sew3ZDOu/kNkuSUxBy1VrYNUPofuM1sC7kifkLxJmZ5YyFmOWe+dJJ\nURRCAiTT6ttoM+KT+i8goAW4JuWyKfdzadKFAIAvGr91a6U7LTYAkQ4UZsTxCWBtNpg7XQ8hms0w\nJhO633gNYFlE3H4XeLKpK8od7i4FBWpCZ6a6eQCltT1e2R53BYZl8fz7Jahq7B/3nVKowKr4FRPu\nLjniVM2ZPR6xkUAgeAZDXS0YgwHy/Hy3F2u6+vWw2Ude4EgIIoFraIpGuDTUYZt3vzmOFzaXeSV3\nBgACL1oNaXYODNVVGPz2a6+M6QmIMzOLYRkG+opy8BTKM2R3jWYbrLbpV3z9qmkHhi06XBR/PoIl\nU5fzS1DGISckEw2aZhwbqHP7eJPFNuEPnYgAnEnv1g9g7VEj8MLVkGa4vhNxNhqzFo2aZqQEJCJQ\nPD4XhUdReOWTCmh0/lGLhaYoPH3HQlx3fqrH+pRlZYOnUEJ76ADZ+SMQ/IhThTLdDzH7+mArfv/P\n3bC7sCLda+jHga4jbo9BILjD8rxo/PGWQtC0d5xriqYRccdd4AUEoO/Tj2Gsn1igwN8gzswsxtzS\nDLtWC1nu/DPUqvZVdePX/9iN2tbpqTGdE7UIiyOLcEHcsumaiksSLwIAbHNzd2b74TZs+NdedPXr\nx3036sCZWkjRMl1pCTS7foIoNg7BV149rb5UIiUeL34AV6dcOuH3GfGB+Pfvz0egwrMFOKcDz8NS\nkxSfD0XxYjA6HXQn1QIJBIJvYRkGupIS0DIZJGnuhz3fdnEGfnNdvtP7hZWx4c3qTdh4bCspikng\nlPgIBYQC7wpJ8BVKRN51N8Cy6HrtP7DrxgsU+BvEmZnF6CaRZF5ZEIOX7jsXydHuJ+yfTrgsDDdm\nXgsBb/rFnWIVUVgWvQSLIgrAsK7HaRZmhOGFXy1F9AQS06LomJMiAHM7r8GmGYL6nf+CEggQcdcv\nQAumf77CpKGIU8ac8ZnOaB3bIeN5KWnRHXqHjPhgxwm0dHumroCKhJoRCH6FqakRds0Q5PPzQfHc\nfwGkKAoJkc4LqX5a/wXahjtQHFmIlICp5eUQCBNxVF2Oyr6acZ83dGjw6a5Gr9khTc9A8OVXwjYw\ngO633/R7sRuX3jjKy8tx0003AQBaW1uxfv163HjjjXjqqafG2mzduhXXXHMN1q1bh507d3JiLME9\n9OVlAI8HWVbWuO+EAp7XVDJc5br0K7EidqlbcpaBChEkoolFDCg+f86LALAsi+7/vgm7bhgha38G\nUVQ0Z2N9faAFf3r3CAwmK2djTIc+jQlCgedECUSxsRDFxkFfWTHjlF8IhNnI8OGR8gByN1XMPv6p\nAbvKO13KSyjpqcBP7fsQKQvHdWlXTslOAmEihswabDy2BRtrto6r37bjaDtCAsRedSqCLrkMkoxM\n6MtKMbTjO6+NOxWcvs2+8cYbeOyxx2C1jrygPPvss9iwYQM2bdoEhmGwY8cO9PX1YePGjdiyZQve\neOMNvPDCC2PtCb7BNjQIc2sLpGkZoMWnEv3NVjt6h4x+72W7i3rQgGHD+BwNccJJEYD2Nh9Y5Xs0\nP34PQ1UlpFnZCDhvJadjrV2RjGuWJU3qXPqazPhAXLM8ecLwtx/b9uCp/c9DY3Zv10a5ZClgt2P4\n4EFPmUkgEKaAtb8Pmp0/gB8YBOkEC3iOyEsNQX3HxMV/T6fP2I/3jn0EIS3AHdk3QsgjamcEzxEg\nUuHqlMugtxnwTvXmM6JUfnF5Fs7NjfKqMAVF04i86xfgKZTo/WgrTE3e2xlyF6fOTHx8PF5++eWx\n/1dXV6OwsBAAsGzZMuzbtw8VFRUoKCgAn8+HXC5HQkICamtrubOa4BR9RQUAQDb/zBCzzj49nt10\nFF/snz2hVwdr1PjrphK0qsfHdUrSMwAAXa+/Cmt/n7dN8ynmzg70frgFtFyOiNvuPCNvigsoikJ2\nUvCMUAE6O8HXYregx9iHRk2zW/0oFi0GeDwSakYg+Ji+jz8Ca7Mh5Oq1oAXuORnJUSrSY7/OAAAg\nAElEQVTcvibTaZK1jbEjQKzCuvSr3VZAJBBc4dzoYuSGZKFuqAHbW3aO+55lWWi8JNUMAHxVACLu\n+gXAMOh69T+wG8bnJ/sDTt9uVq1aBd5psaenr+jLZDLodDro9XooFIqxz6VSKYaHPROXTpgaukkk\nmRMjlfj7vedgTbH7xQw7dd14o3Ij+o3TEw7wNAXpoXjh3qXISgwa952iaBECV6+BVd2Ntr8+A3PH\n3JBpZm02dL/+KlirFeE33wZ+wHjVMXfpMfSiRds2blfvw531OFijnhG7fSzL4q0vj+Gv75Wc8Xny\nybj3Bo17ybx8pRKy7ByYW1vm7O4fgeBrjA31GD50AKKERCgWFbt8XM+QERar68qeEbIwPFx0HxZF\nTq0YJ4HgDIqicEPGWqiESnzR9B2aNKcKajIsixe3luO/Xx/3qk2yeVkIWnMprH29UL/zX7981rsd\nD0Kftrqr1+uhVCohl8uhO03tYPRzVwgNVThvNAvhct6MxYL6YzWQxEQjOivZI32yLIt/VW7Dsd4T\nuChjGTJCp1bZ3dV5MwyD/e1HsShmAfhu5NBMRNgv70BHRAia334XHX97Fpl/fATKDPeVbqaKN69x\n1m7H4NESdG77Eua2VoRdsBJJF63wSN+fHdmG7Q278eR592NeaNrY5+cXxeOLPU24+JykMxL//fW3\nvXJRPDLiAyGXnlq9VQVmgFfGQ6u+zW276YtX4Xh5Gaxlh4H8eX47bwJhNsKyLHq3fAAACLvuerd2\noHeXd+JAtRpP37HQ5fBYAe2fYbSE2YNcKMOtWeuwufbTM95/aIrCFeckIiHS+8+Y4MuvhLGuFrqj\nR9D1yssIv+U28KRTr1Xnadz+Vc6bNw+HDx9GUVERdu3aheLiYuTk5ODFF1+ExWKB2WxGY2MjUlNd\nq+nQ2zv3dnBCQxWczltfVQHGbIZ4Xs64cU60DyE6RA6p2L1Tf7i7FMd6TyA3JAuxgvgp2e/OvL9q\n2o4vm7bj+vQhnBPtfKXNZmdQ1zYEiYiPxAnUaITnnI9wSgD1O/9F1R+fRNQ990KWnev2HNyF63M9\ninVgANo9u6DZvQu2wZFK95L0DCivvNYj49sYG/a1HIVSqEAwws/oM1gmwC0XpWFg4NT2s7fmPRXi\nQ6Qw6s0w6s/cqo+Tx6BpsA3t3f0QuRELz8SngZbJoP5hJxJuvhF9AwZPm8w5xAEjzFSGDx+EqbEB\n8sIiSFLTnB9wGtcsT8Y5OZF+m+dHmLukBabg0YUbxgkina5CO6A1IVAh8kpoN8XjIfLuX6HrlZeh\nO3oEppZmRP78HkiSkjgf2xXcDqJ/6KGH8NJLL2HdunWw2WxYvXo1QkJCcNNNN2H9+vW49dZbsWHD\nBgiFJDHOV+jKJ5Zkttrs2PpjPd7++phb/VkZG/7X8DUENB/XpF7mMTsdsTSqGAJagK+bv4fV7lxM\norvfgI9/asTg8OSxpKql5yLqnl8DLIuOf/4ftAf3e9Jkr8MyDHTlZej45z/Q9NDv0P/5Z2CMBqhW\nnI+4x59C7IMPgxaLPTLWsYE66G0GFITPB02N3DaOtwx6pPiqr+geOFM0IjkgATyKRr9xwK1+aIEA\nioXFsGu1GCwt87SZBAJhEhiLBX0ffQiKz0fINddOqY/wIOnk/bOMX4bUEOYGjpRd23t1ePqdI2j2\nUKkBV+CrVIh54CEEXXoZbP39aHvuGQx+941f/EYo1sdW+OvqLZdwuWrNsiyaHn4AjMGA5Bf/CYo/\n/RWnH9v24KMTn2Nl7DJcnTpxoURXcHfen9V/he2tO7E29XKcF3vOlMc9G0NdLTr/+Q8wRiNC192A\nwAtWeazvs+HiXFsHBqDduxua3T/BNjDy4i1KSETAshVQLFzkMQfmdN6qeg9He8rx+8JfI14ZC5Zl\n8ern1Rg2WPHg9fnj2vvzzgwAlNT14t1vjuMXl2chM2Ek16rX0A8ACJUGu92fqakRrc88DVVuDsLu\nvZ9zsQVPQ3ZmHOPP1zJX+PtvGAAGvvoCfZ98hMDVaxC69mcuH/djSTtMVjsuKIiBgH/mC+Pp8/6w\n7n8w2ky4Lv0qt3ZrZxoz4VxzwUye97DBgqYuLXKTQ9w+1hPzNhyrQdfrr4wVZo+4/S7w5OPr/XkS\nR88psrc6y7B0dsLW3w9F0UKPODIAYLZbIBfIcGH8eR7pz1UuiF+O3R378W3LD1gStdBjDxNpWjpi\nf/8HtP/jBfRufg92nRbBV1zt1ypcLMNAX1UJza6dI/WDWBa0WAzV8vOgWr4C4rh4zsY22Uyo6KtB\nmCQEcYqRQpkUReHuK7Kh0Y+Xw54J5CQF4W/3LIWAf1qOzxScmFFECYmQZudCU1EB+tOPETrFVWIC\ngeAaNs0Q+r/8AjyFAkFr3Ftky4gPxLa9zbDYmHHOzChlPZXY2b4XEUS1jOBHsCwLiqKgkArPcGTq\n2zVIjlZ67T1GmjkP8U/8Cd1vvAZ9RTlannockT+/2+1QT0/Be/LJJ5/0ycgnMUxQG2S2I5OJOJu3\ndu9uGI7VIOjiSyCKjT3ju+MtgzBZ7VBIBW5d8CkBiVgesxQSwfRW/N2dt5AnhJWxobr/OALFKsQr\nYx22t9rs2FfZjRb1MOIjHK8081UqyBcUQF9RDn1ZKexaDWQ5uR6/EUz3XFsHBzG04zt0v/UGNDt/\ngLW7G6KERIRcfhUibrsTioJC8FXTVypzaANjg5gnQnpQCuKUMbAzDOiTfyexcOIXAS6vcU/Ao2nw\nnMiwugNFUZDl5MJYXgJdaSkE4REQxcR4rH+ukcnG194hnMKfr2Wu8PffcO/WD2BqbEDoz9ZB6uYL\nlEIqREF6GIQTODIymQit/V34d8VboEHh1/l3IUCkmqCX2YO/n2uumEnzttgt2Fr3GRq1LcgIOjMn\nfVd5Jzb/cAJLcyIndc5Px1PzpsViKIoXg+LzoS8rhXbfXoCmIUlJ5cSpcvScIjszswx9RTlAUZBl\n54z7rqy+D/UdGjx6k/uykkKewBPmuc3KuHMRLg1FQfh8p20pisLx1iEUZYS51LcwNAyxDz+Cjn+8\nAM1PO2HX6RBx5y9AC3wzVwBgTCaYmptgamyAoa4OhpoqgGFAicRQLV8B1bIVEMcneNUmCV+MVfEr\nAABWG4Mn/3sIqxfF4dzcKK/awQUn2odQ36HBxYumv7PFk8mQ+cjDKH/wYajfeQvCiAivnysCYS5g\nbmuDZvcuCKOioTp3ucvHaXRm8Pk0ZOLJ7/FWuxVvVr0Ho82EmzJ/RurJEPwCO8vg+MAJ9JsGkRGY\nivSglLHvshODkJ0YBKmD65orKJpG8CWXQZKahu7XX0H/px/DWHscEXf8HHyV9xYByM6MD+BqNcCu\n06Hng00QJyUjcOX4PJDspGAsm+/dCrKnM5V5C2gBouWRLtlM0xQK0kMRETx5Que4Y8RiKBYWw9RQ\nD0NVJYwN9VAsKADF98xNwdGcWYaBtbsLuooyaH76Ef2ffYzeLR9Au28PDMdqYO1RQxQbh+DLr0Lk\n7XdAUVDkkXox04FHU0iPC4DJYkd0yOSyjDNlxeuTnxoQqBAjKWr89jzLsug3DUAqcP16CogKhS0g\nFMMH9kNfWQHFwmJOcpg8DdmZccxMuJY9jb/+hlmWRfcbr8La24uIO34OYUSEy8ceOtaDf31SifzU\nUMglE9/jt7fuxN62wyiOKMQlSdzlU/oT/nquuWYmzVtA85GgjMOB7iM4NlCHgvD5EPNHni0SEX9M\nkc9staOkrhfRoZPnr3Axb0FwCJSLl8LS1QlDVSW0B/ZBHBcPQWiox8Zw9JwizowP4OoHpCs5Al3J\nUQScd77P4hYd4a83DloggKJoEcwd7TBUVUJfXQ15/gLQoum/4J0+Z7tOB2PdcWj378PA11+id/N7\nGPzuG+jLSmFuaQZjMkGSlAxF0UIEXrgaodddj6DVF0OckOAx58oTKGVCh44M4L/n+mwK0sOQHK2a\n0Fl+99gWfHxiGxZFFow9NJwhk4lgUwYBPB70pSUwNTVCWbzY7wUBiDPjmJlwLXsaf/0N6yvKMfDl\nNkizcxBy+ZVuHRsfoUB+aijCAiWTLpBlx6TAaLDg8pSLp13jbKbgr+eaa2bavAPFKvAoGhV91TjU\nXYIwaQgiZGdGorz15TH0DBmRnxoy6TXO1bxpkQiKhcXgSSTQlZdBu28vWIaBJDXNI89AEmY2R9BX\nTCzJzLAsPth+AsVZ4WdolDuizziAEEmQx230Bp/vaULvkBF3XDrP5WNooRBRv7wX6o1vQ7tnN9qe\n+wtiNjwAQbD7SiGs3Q7b4ACsfX3oOjKAvooaGBsbYO3uPqOdIDwcsvl5kCQlQ5yUDFF0jMdEGzyN\n1WbH1wdasaoods7UZEhRJeJQdwk+rPscd+Xc5NaxQWsuhbmtFbojh9HzwSaE33QrN0YSCHMI1mZD\n74ebAZrG/2/vzsOjqu7Hj7/v7GtmkpnJnpA9BMIiOyLIIgqiIlaFKta9SvXr8rO2uFSrlbpra1tb\n7aKVasGqdUGkiCjIvidsCWFNyL4vk22W+/tjYCCShITsyXk9j49M5t6bczJz77mfe875HMeNCy7o\nGKGtpGIG0Km0XB0/64KOLQhd7fJB09AoNXx2ZCVbC3YxwpHa5P0bpiVgMWp6bASOJEkEXj4LXUIS\nBW//mbIVn1N3KJPQu+9FHRjYZb93YNyVDACyx4Nz315UQTY0EU0nHnu9MsFBevYeLW1TMFNeX8Fv\ntr7CmOCR3DKk7ekuu4tX9vrXOmmO2aghJab9J42kVBJy6x0oTWbKV60k+/nniHz4UbQREU22OztY\ncZWW4CopwX3q/67SEtzl5eD1NtlHodNhSBmKLj4OXVw8+th4lObenQ630eNCpVCikBS4PTIlVfV8\ntfUE102J7+midaqcohqWr81i8vBwxg85Mz5+YvhYthTsZE/xXvaWHGCYve3BsSRJhN5+FzmFhVSu\n+w5tZDTWadO7oviCMGBUrPsWV0EBlqnT0YZHnH+HU9KPlJJ1soLZ4we1e8FoQehNJEliWtQlDA5K\nxKw+dyhZoPlM78WJgmpOFtcwaVhYdxYRAH1cHNFP/ZrCf75Dzc4dnHjmV4TecTem4eef/3whxFnd\nT9QdOYy3thbz+AnnROQqpYKZY1rPBHa2Vce/we11E2+N6eRSdtz3uVv4LmcDj465v8WhP9Muansj\n90OSJOG4/kaUZjMl/1lOzou/xTp1Gu6K8laDlVM7o7IGoo9PQGWzobbbCYqNxmUPRxMW1uuHGv3Q\nN9nr2Ji3jZ8O+wnRAZHccWUK3l6wOFZn02mUTBoWxqikpmN7FZKCHydfx/Pbf8fyzE9JCkxoV3pw\nhVZL+P0PkP2bZyha9j6a8HAMyYM7u/iCMCB4nE5KP/8UhV6PbW77hpdFOozsyCiivLoeg65r18IQ\nhO5wvsQUHq+Xv604wLWT47qpROdSGoyE3Xsfld99S/HyD8h743Ws02dgu/Y6lIbWh6q3lwhm+gln\nmm/lceOwplGv2+NFpWz7TXRJXSmb8rcTrLczPrT9Wc+6WlVjNQW1RXx1/BvmJcxpddvT+dgvRNAV\ns1GazBT+8x+UrVzh+2EzwYraZkdtd6Cy2VEHBZ0zTKyvLsolyzLbC3dT46pB6T7T+Ct68Vo8F8ph\n1eOw6pt9L9wUyszoqfzvxFq+zdnArJj29a6obXbCFt3HyddeJv/PfyL6V09f0NBFQRjoSld8jtfp\nxH79jajMAe3aNyhAxx1zUpp971hlNuGm0H69KKYwcBTXluLFS4jBwZO3jkGr7tl5X5IkYZ02HV18\nPAVv/4WKtd9QvWM7jhvmY55wcacNhxPBTD/hTE9D0mgwDG56wV72TRb5pbXcO3coZsP5L9ZfHvsa\nr+xlTtzlKHvh5MeZ0VPZmr+Db3M2cHHYWEKMzadh/mT9UTbty+f5n05oU9715lgmXYI+Lg5XWZkv\nYAkK6tG0zd0ppyaXwtpiBluG8OLSvdw6K5nRyW1Led1XybJMaVU9dkvTwGZWzAyMagNTIi++oOMa\nkgcTvOBmit5/j7w//p6oxU92SnIJQRgoGgsLqFi7BrXdgbWZTJ0taWj0UNvgbjL05mzFtaX8cc/f\nCDbYeXTM/a0OXxaE3s4re3n3wL/Jq8nnusSruSR8vP+9r7acIMxmZGRizzxM00UPIvrpZ6n4+n+U\nrvicgr//lcr16wi+6ZZz1kS8EOLM7Qcai4pozM/DkDIEhaZpwLJgRiLTLorA2EIayrPlOwvZXrCb\nCFMYo4KHd1VxO0SjVHNd4tV4ZA//yfocuYVhTyPibTx28+gLDmT8vy8sHOPQVDQhIQMmkAHYXrAb\ngCnRY3nq1jHEhffvReMA3vgonT99su+c75RGqWZG9BTUigt/9mOdNh3LpVNpyMmh4J2/tfi9FQTh\nXMUffQgeD/brb2zXdfhwXiVP/X0rB4+XnfOebz2ZpdR76pkaOUkEMkKfp5AUTI+ajEqhYlnmJ/wl\n/V2qGqspr25gR2bReRcT7/LyqdUEXXkVMb/5LaZRo6nLOsSJ3zxN0bL38dTWdujYIjVzD+jstHhV\nmzdRu2+vL4NETEyT9xQKiXC7sU1deWqFGq1Sw7jQ0YQYOi83+GmdVe8Qg4OjlSfIKM8iyhzRbO9M\nUICuV0z07GupH8H3dOf9g/9BISn58eDrMOu17c5g1hfrnRBhYdaE6A4NpWut3sahqdRlZlC7by+S\nSoUhKfmCf09nE6mZW9fXvsudobecw7UZByn95CP0iUnYb5jfrmEpwVY941NCcATqUauaBisfZX3O\n3tKDXBw2ltmxl/l/3lvq3Z0GYp2hf9Y73BTKuNBR5NUUcKAsk635O4kJDOP6iSP87bhGq6a+3tVj\nZVQaDJjHjkcXF0f9kSPU7k2nauP3qAIsaCIjW00p3RLxKKIfcKafmi9zVpaIBpeHzOzydj0B1qm0\nXBEznaG23nOT1RxJkrgh6RoSrXEE6VrPWlZT5+qXk9a7klf2YlHaMdRFUVffTKKDfspu1fsDmbKq\n+k7vPZFUKsLuvQ9VUBCln35CzZ7dnXp8QehvZK+X4uX/BsBx44ILGl9vs+jOeRizszCN9bmbCTeG\nckPS3E4pqyD0FlathftG3smPEq+m3tNASV2Z/9xxub384g/rOZpX1cOlBGPqcAY98xy2a6/DW19P\nwd/f5uRLz9NwMqfdxxLBTB/nra+j7lAm2uhBTXJ4l1TW8+6qTL7ZebIHS9d1Qo0hPDTqXiLN4S1u\n8+Xm4/zyL5soLq/rvoL1AyqFip+OuIUE1TjKqup7ujjdLruwmmf/uYPjBS0nbnB53Rd0bJXFQvh9\nDyCp1RT87S0a8nIvtJjCebjdbn7xi19w8803c+ONN7J27Vqys7O56aabWLhwIc8880xPF1E4j6pN\nG2nIycY88WJ0sW3PypRX4uS9VRlU1jQ0+/6RyuNolBruTF2IRkz8F/qh00POnhz3CJeeNd+zvLqe\nIbE2YsN6x9IQCrUa21XXEPPsEowXjfINPXv2aYqW/xtPXdvv3cQwsx7QmV2bNenpVG/dgmXyFAyD\nz6yDEWDQMH1UBFHBJpTtyGbWlbq7SzckyMBVE2OwmHpuCE1f6sZudHk4mF1OcKABvVrDiLgQrBf4\nt+tL9f4hhUIiPiKA5Kjme/2yyo/y+91vEWJ0EGxoOpmyLfVWWa2oHQ6qt26hdv9+AiZcfM5ct+7W\nH4eZffrppzidTl5//XWuuOIKFi1aREZGBvfddx/3338/3377LR6Ph7i4898k99Xvckf09Dnsra8n\n709vgCwTft8DKPXNZxxsjiRJHM2vQqlQEGo7d5HMobbBjAkZec75Cz1f754wEOsMA6PeRrWhSY+m\nUa9m8ugof713ZBRRXFF33sVku5rSYCRg3Hi0MbFnhp5t2oDKakUT4Rt6JoaZ9WNnhpiNPOc9hSSh\n6eG0fD3JYtQM6Pq3lVf2DSWrd3l4+/MD5Jc6e7hEPcts0JAaa/O//uHfw6DWU9lYxfLM/9LoubCG\nMGDcBAJnz8FVVEj+239G9ng6VGbhXLNnz+bBBx8EwOPxoFQqOXDgAGPGjAFgypQpbN68uSeLKLSi\nbNVKPJWVBF4xG3VQULv2NenVzJ+e2GrmJru+fccUhP5kV1E66UUZfPjt4Qt+aNkVTMNHMOjZ57DN\nnYe3tpaCv77FyZdfoCG39VEMIpjpw2SvF2d6GkqzGV1MrP/nH649zK5DxW06xuGKY+wqSvff0PY3\nsiyTXVhNUYUYataczw+u49Xtf8HlcRFg0HDfvNRedWHraau3ZfPGx3txuc+cHxGmMGZETaG0vpyV\nx9Zc8LHt836EcfgIavfvo+Tj/3RGcYWz6PV6DAYDNTU1PPjggzz88MNN5kEZjUaqq/veGlADgaus\nlPLVq1BarATNurLN+8myLK71gnAeje5Glmf+l7f2/YPESUewBPraN5fbQ25Jzz/MVKg12K6eS8yz\nv8U48iLqDmVy4plftbpPz6d7Ei5Yw4njeKqqCLj4Ev/q8rIsExNmJiO7/JwVzX9IlmU+zvqC7OqT\nPDHu/xFuCu2OYneJyoZq1p3cyJzYmU3Wx9mRWcz7qzNZ8tMJPVi63scre/n0yEq+yV+P0quluK6U\ncFMoydGtJ1QYaJKjAxk3JOScTEhXxl7GrqI0vslZz9jQi4gwhbX72JJCQehd95D922cpX70KbVQU\nARMndVbRBSA/P5/777+fhQsXMmfOHF5++WX/e06nk4CAti2+6HD0jvHl3a2n6n3oX/9Abmwk9t67\nCYls+7oYJ4uqWfLeTu64eiiXjYu+4N8/ED/vgVhnGLj1fmrag/x1xwfsKdlLZmUWPx42l+PpVpz1\nHh65uZcsmO4wE/7Mk5Rt38HRv/691U1FMNOH1aSnAWAccSaLmSRJjEsJYVxKyHn3TyvZT3b1SUYF\nD+/TgQzAquNrWJ+7mQCtmamRZ24IxyQ7GBRqxqjzrU1QWFZLdZ2LhIj+v25Kc1xuD7uPFLC7YQ3p\nJfsJ1juY5fhRn//8u8rZefkbXB5KKuuJsBvRKDXMT57Hm2n/4N8Zn/DI6J9dUKYlpcFAxP0Pkr3k\nWQr/+Q7eRheWKZd22qrIA1lJSQl33nknTz31FBMm+B5mpKSksH37dsaOHcv69ev9Pz+f4uKB14Pj\ncJh7pN51R49S/N16tNGDkFJHt6sMWgmeu2scbo/s36/R42LpweXMjrmsTde5nqp3TxqIdYaBXW+j\n28oDI+5lY942PjvyFf/YtZxk4zDuGrfA/zfxynKHliroNDHJRP16SaubiGFmfZgzPQ2USgxDUgFf\nyr22ppP1yl5WHP0fEhJzYi/vymJ2iytjZ6JX6VhxdDXVjTX+n0uSRLD1zMTRpasze0VKwp5S1VDL\ne4ffJb1kP8mBCTw65j7GJ7Q9S9BA5fXKvL58D+v2nBm3O9Q2mBlRU7gy9rIOBR+a0DDCf/Z/SBot\nRUvfJf+tP3d4ATEB3nrrLaqqqnjzzTe55ZZb+MlPfsJDDz3EG2+8wYIFC3C73cyaNeu8x2kobtuQ\nXaHjfKmYPwDAMf/H/hEH51Ne3YDb4xsqYzZoCDSfGSr7UdZn7CpKZ0Pe1s4vsCD0YQpJweSICTw9\n4VHGh45mbspUDKcf/JbX8pt3d/jPq552vsVyRc9MH+WuKKfhxHEMKUP8WV6+3Z3LhvQ8Fl2bSpjN\n2Or+Owr3kO8sZELoGEKbWXSyrzFrTMyJvZyPsj7ni6OruGnw9c1ud92UeAaFmvyvD54oZ3C0tV8/\nCT9RUI1apSDcbiTQYCTBEUaQMYmbU65rMiRPaJlCIXH9tATiwpsOS7ou8apOOb4hZQiDnn6W/Lf/\nTM2ObTScOEbYTxe1Kx2t0NQTTzzBE088cc7Ply5d2q7j7Pjpz3DcuADrjJn9+jrR02RZpuiDf1F/\n5DCm0WMwJA9u874rNh+nuKKOB68fjvKsAGhbwS425m0j0hTOvPi2z70RhIHErDHxkyHzm/zs8MlK\nLhkehqqXZMM9n75RSuEczvR0oOlCmTPHRDJ/eiJBZt15999WsAulpOTKs1Y+7uumREwkzBjCprzt\nZFc1v75OXHiAv7Hbd6yUd1YebDK5uz86klfJv1ZnIssyCknB/WN+wi1DrheBTDslRFj8Xe7ZhdXU\n1HXuCspqm42oRxcTdOVVuEpKyH5hCeWrV3X64p1C+6gDAihe9gGF7/wNr6t/p3HtSWVffkHld2vR\nREYRcusd7dr3pssSmToyokkgU+As4t+Zn6BTarkz9WbUytaf7AqCcMakYWHMGB1JjctJYW0xX+/I\naXHdpt5ABDN9VE0zKZklSWJobBBazflvUhcNv50HLvoptn6UnlKpUHJD4lzfGgOVJ867fViQkXvn\npvrTN5dU1NHg6pspcusa3P6bXlmW+esXB/B4fUHapSPDmXtJrP+pskqhEk+YO6CwrJZXl+/hRGHn\nj7WWVCrs111PxEOPoDQaKf5wGXl/+B0ekXWrx4x49SW0MbFUbdrIyZdewF1R3tNF6ncqN6yn9NNP\nUNlsRD70/1Aazr/mhdvjpbTSt6ivUqFokvDG7XXz933/otHTyE2DryfY0HoyHEEQmvfp4ZUs2foa\nXx5bjaTsvQ9+xaKZPaCjCzV5XY0ULf0naocD+zXXIssyaYdLcQTq2jxZSyEpCNJ1b+aq7ligyq4P\nYnzoaIbYks67rUGn8o+t9nplXlm+B6NeRaTDdJ49266r6vz1jhwi7EZ/F/Ajf9rIpNRQdBpfoLLs\nmyyGxVtB5UKn0mK3tH3Buc7QnxcjM+hUDI+3NZtEwmDQsC07DYfe3rF5NMHBBEyYSMPJHGr37aV6\n2xa0MbGobW3P7NQe/XHRzM6iMhhQDh+Nq6zUt5Db1i3oExLbvfZJX9Nd53BN+h4K/voWCoOBqEcX\no7a3LfDIzC7n9Y/SGBZnI8DQdNFZhaRArVTj0NuYET2lXeXpz9eulgzEOoOod0jHHXAAACAASURB\nVFt4ZC+HK45Sq80jvXQvDoODilIlZdUN2ALOPwqoM7XWTolgpgd09ASqPbifqo0bsFx8CcahqVTX\nufhgzSFyCp0Mj7ed/wA9pLsuHAZ1+2/c3R4ZSZK4ZFgYkiQhyzJVzkZ0mo5NK2trnWvr3UiSb24G\nwJ7DJRi0Kn8v20sf7CIuPADzqUb7vVWZJEZa/GvCVDobiQ4xYdT7hlIkx2v56MSHbM7bxpiQi1Ap\nund6XH9uJCRJIsB45uZp96FiQgJ9qyxvzN/K23uWku8sZHBQUoeGtih0OszjJ6JQq6lJ20PVxg0g\nSegTkzq9Z00EM62ra/BgumgUSoOBml07qd68CZXVii56UE8Xrct0xzlcd/QIeW/8DkmhIPLhn7fr\n7+mw6okONhFpNzU7rj/KHE5KGx5q/VB/vna1ZCDWGUS92yLMGMKk8HG4vC4OlB5ie+Eudhamk6Ab\n3qkPfttCBDO9TEdPoPKvV9Nw/Bj2eT9CbXegVSuZPDyclEGBKBW9d/hQb75wKBUSsWEB/pvE7RlF\nLFubxZQR4YAv2Di9Hfiy5ygkyd+I5pc6USok1Cpf8HGioBqFQiLIaqC2tpHN+wrQaZT+FNFL/5eJ\nxaTxByOvLttNcKAB+6nMa++tyiDUZsBx6vXBE+WE2YzYLL4nITGhZkIC9f7flxpnI6smk7U53/NJ\n1gpWn1xDWX05cZZBXBQ8rNvnx/Tmz7ozfbcnly83n2BcSjBatZJwm52MwqMcKDvEzqI0YgOiCdRZ\nL/j40qngxTB4CLUH9uHcs5u6Q5kYhw5Foeu83jYRzLSutrbR91nEJ6BLSKRm925qtm/DU1ONIWVo\nm7Nu9SVdfQ43FuRz8tWXkBsaCF90P8aUIW3ar6CsFtOphzYOq77TJygPlGvX2QZinUHUu61UChVD\nbMkMsw+l0duIXWfnqtRx/ge/f/xkL4mRFpQqL17Z22X3GyKY6WU6cgL5Mr4sBVkm+KaFTRrR8wUy\nsiz36FyJvnThyCutZczgYIJOdaP+6b97MenVhAb5xnK/9fl+zIYzr//+5UECjBr/63e/ysBi0hIf\nFUhtbSMfrzuCLUBHqM33/vfp+YQEGvzbVzobCbcb/cGN1awlLMiAXuvrURmV5PAHMgCBZq0/kDnt\no6zP2VWUjkf2MDgokenRU5gbP7vbe2Wgb33WHRFsNTBpWJi/x8xhtZJq9qVK31dykC0FO1ArVMRa\nojt07qltNgImTqKxIJ/a/fuo2rQJbWQkmuDzryfVFiKYad3Z32WNIxjT6LHUZhzEmZ5GXdYhjMOH\no9D2r79hV57D7opycl5+AU9lJSE/uY2AcW1b76fB5eH5f+1EIUlNMgt6ZW+ntW0D5dp1toFYZxD1\nbi+L1sxIRyqjwob6z7e80lq2HCjk8rFRbC3Yye92v8WhsqM4XU60Si0mtbFTz82WiGCmB3TkBGrM\ny6N85QqMI0cRMG48n288Rn5pLZHBJv8QpeZUNFTy2s430am0F7RaeWfoqQtHTnUeARpTu06oCLvR\nH8gAlFU3EOkw+efYOOvdRDiMWE4FHy6PlwiHyT92W6lUEGE3EmI3UVvrC1TCbEb/sLGxg4MJPSt9\ndlKU1R/IAARb9f5ABqDG5eRAaSbrczcjIeEwnDt3wqG3MSliPNcnXsO4sNEMCojsseB1oDQSapXC\nn0Citt7NlgOFRNiMJAUmkGCN5WBpJmUNFUwIG4tS6tgTZIVGg3nseJQmE870PVRt2oi3oQFD8uAO\n9wyIYKZ1P/wuK41GAiZe7Asu9+2lesc29MmDUVkuvBeut+mqc9hTW0vuay/jKijANncegTOvaPO+\nKqWCMcnBmA0aLKeGehY4i3gr/Z/oVDrCjB0P7gfKtetsA7HOIOrdGQIMGi4ZFoZCIZFfU8ix8jxy\na09ysOwQ3+duZlP+dizagE5ZmLu1dkqsM9PHOE9lMTON8KVkTo6ysuVAIVOk8Bb3qXXV8ac9fyfP\nWUCdu75bytlbrMlex38Pf0mIIZiRjlSG2VMYFBCFop03lldOaDqWe8boyCavJw9v+vcfO7jp2j3R\nIeYmr9sSZOQ7C9mYu5VDFUfIqylAxpetzCN7GWJLPmf7WEv/Hb/fF/xtxQGSYs5MCk8KTOCxcQ/T\n6GlE3Um9Y5IkEThjJvqERPLf+jPl//uKuqxMwu5ehNohMjZ1J4VOR9i991H25ReUfvZfcl5YQuht\nd2IeN76ni9ZreV0u8t78Aw05OVgunUbQVde0ab+i8lp/b3SgWUugWYvH62FN9jpWHl+D2+smqzyC\nUcHDu7gGgiD80OkH6ePDRuMti0ChbcBrLCaj7BD7ijNprO/6YbiiZ6YHdCQqLvnkI9zlZYTcchsK\nrS9L1ciEljMnubxu/pL+Dieqc5gSMZErY3tu4beeeApi1Voori0lpyaXrIojbMrfzobcLRjVBqLM\nEV3++1uqs8vjorC2mKOVxymrL2+2p+VQ+WH+e+RL6t31xFvjmBg2hjlxlzMpfFy7g7HuNhCfeI1M\nsDN6SCiuRt/8qqWrMzFpdEQ7Oj/rlcpqxTLpElylZdTu20vVpg0oDAa0kVEX1EsjemZa19J3WZIk\nDMmD0UZFU7N7F9XbtiC73eiTB/f59OedfQ7LXi+Ff38bZ3oaxotGEXrH3W3+rn624RirtuUwMTUE\nhSRxsjqPv+x9l+2FuzGpjdw6ZEG7s5a1ZCBeuwZinUHUuytEBZuIDLISZQ5nhD2V71ZrmZAQi8N6\nbrr1fx5YxpGKY6gVKqxay3nva0TPTD/hqamh7nAWurh4ZIMRt8fb6uRHr+zlvQPLyKo4ykhHKjck\nze3zDWx7BekCWTTidho8jWSUHWJvyUH2lRxEr+relIIAJ6vz+OTwCopqS6hoqPT3tCRa45rtaUmw\nxvPQRfcQExAtFnzrA7QaJQadGmd1PQ0uD1k5FfxoSrz//boGt3/oYK2rlnpPQ4fSoyt0ekLv+imG\nIUMoen8pRf96j7KVXxI05yoskyYjqcTlvbuYLhpF9BO/Iu+Pb1C2cgUNOdmE3n1vm9ZLGQhkWab4\nw2VUb9+GPjGJsLvvbVfQveCyRDKzK1AqFHhlL+8e+Df5zkImhI7hR4lXYVCLv7Mg9DoSLJyZzOBo\n3wM9l9vDq8vT+PmCkXhws7fkIHXuOtbmfI9RbSDVlsJw+xCG2Ye0O4mAaO36EOe+dJBljMNHsP9Y\nGe/9L5O7rhpCyqDmb4hyawpILzlAvCWGW4f8uNc/ze9KWqWGEY5URjhS8creFldV/8+hz9CrdAyz\nDyHKHNHq36ze3cDRyuNUNFRS3lBJRX0lFQ2VGNR6bh960znbKyQFmeWHsWgCSLDG4tDbCTbYW5zD\nZNGasWjNzb4n9G5atZJn7hjnf3hwsriGNz5K54V7JiJJ8H7Gx2SWH2Zhyg2MdKRe8O+RJAnLpMkY\nhw6jbNVKKtd9S9HSf1L25QoR1HQzbXgE0U88Rf7bf8a5N53sJc8Scf8DaMJaHgI8UJSvXkXFmtVo\nwsMJv/9BFBrNefdpdHkoraonzGZEIUn+dk4hKbhp8PXUu+ubfQgkCELvoJAkUuPOLBeSU+REIfnm\nvqnQ8Ivhj/LRzm0ERlawt/gAWwt2klF2iOGOoe3+XWKYWQ+4kC4+V0kxBf/4G97aWoIX3ERETBgp\ngwJxWHQtroVi0ZpJDkxgauQkdD3QE/FDvaVLV5KkZoMUl9fNu/v/TUZ5FhvztrEpbyuFtcWU1JUR\na4k+Z/uy+gpe3vlH9pYcIKviKDk1uRTXleKW3UyNnAQ0rbNRbWDmoKlcETONCWFjGO4YQrw1ptkh\nZn1db/msu9vZ9T67FzSnqIZIh5HYMF8GpuLqag5VHmJ74W5qGp0kB8Z3KJ2lQqfDmDoMyyVTkGWZ\nukMZOHfvomrTBiSN5rzDz8Qws9a19bus0Ggwj5+A3NiIM20PVVs2AaB2ODo1lXZ36KxzuGrzJor+\n9R6qwEAiH12MynLuYrPNyTpZye//k0ZqrK3Juk4AgTprl103B+K1ayDWGUS9u1ugWcvE1FB/27gz\ns4SyEiW3XXwp06IuwaEYhMEVTGr4ufN/axqdBAa0vK6NCGZ6QHu/SI1FRZx8+UXcpaXY5s7DPHYc\nABaT9ryLOgbqrL1miFJvv3AoJQWXRl5MtDkStUJNYW0xRyqPc6wqm8sHTTtne41CjUqhZlzYaC6N\nvJgrBk1nbvwsLou+1L/ND29uVd283ktP6e2fdVdpqd7BgXpiQn2BjCRJfPVtBalBQ6jXFLG/NIO9\npQdJssZj0hjP2bc9/EHN5NNBTeaZoEatRhMRiaQ89zsogpnWtee7LEkSxqGpqENCqNmzm9p9eylf\n8zX1x46i0GhQO4L7xLo0nXEOO/fvI/+tN1Ho9UT+fDGakLZnG7Nb9Rhs1cQG29Couq8NG4jXroFY\nZxD17glnP+SLCjExZFAgapUSSZLYvKcCpTvA3wt7LL+KKmcjVpOWjXnbGBqW2OJxRTDTA9rzRWos\nKODkKy/gLi/Dft312K66hl2Higk0azt9sbCu1hcuHCqFijBjCCMcqcyInsJQWzIXBQ8jSBd4znwj\npUJJYmAcUeZw7HobJo3xnDVd+kKdu4Kod+vcHi/ThscxKWIsTpeT/aUZmFUWEoNiO6UcZwc1yDJ1\nWYd8Qc3mjc0GNSKYadlftv+LrNJjhJtC0Srb/nfSRkZhnTYDtc2Gu7KSuswMqrdvo3L9d3iqqlDb\nbChNvXcYaUfP4frjx8n9/atIskzEg/8Pfez5v9teWeZIbhUGA3yctYKVJ1fgll0MtQ2+4HK010C8\ndg3EOoOod0+TJKnJenmRDhNx4QHoTi1hsXxtFhq1kkGhZho8DQyyt7ysiAhmekBbv0iN+XnkvPIi\nnooK7DfMJ2j2HDxeL59tOM62A4VMGNo0b7fL6+7wWhZdqbecQG0lSRKBOis2fdAFJ07oa3XuLKLe\nrYsOMaNUKlAqlJhckexIq+Om8ZegV+vwemVcbi/KTnhYcWb42eSmQc2mU0FNpC+oEcFMy97e8T77\nSzNZf3ITlQ1VhBpDMKjbNmRMoVaji4nFOmUqpotGISmVNGRnU5dxgIq131B78ABIoAkJ7XVzmzq0\nHlpRESdfeRFvXR1h9/wM07C2p0x+/as1rC79mCNVRwg1BDMrZgaBuu5bv2cgXrsGYp1B1Lu30WmU\n/kAGIMCoITHSglatxK63iUUze5u2fJEacnM5+fKLeKoqcSy4iaDLZwG+CVVjBwczZnBwk0UyS+rK\neHnHG1i0lk5ZOKwr9NYTqCsNxDqDqHd7BBjVXBQdhyPA95R+/7Eylq7OZNKwMLyylzfT/kF1Yw12\nfVC7egbO1mxQs+dMUGMb2n1PvvuaCWETMCmM5NXkk1GexfrcTVQ0VDLMPqRdx1FZLBiHDcd62Uw0\nERF4a+uoy8zAuWc3FWvX4CopRmkOQGU9txe4J1zoOewqLib39Vdwl5cRfPNPsFw8qdXtD5+sJLfE\nid2i5Z0DH3CMbXhxc0XMdG4behM2feenNm/NQLx2DcQ6g6h3b2ez6NCeWpRalmWRmrmvacjJ4eSr\nL+GpqSb45luwTptxzjZnDzGraXTyp7S/UVpfTmVDVXcWVRCEDlIqFIQGnUktW9foYfIIXwas3JoC\nDpZlcaAsk0+PrGRIUBLjw8YwzJZyQXPhVBYrjvk/JnDWlZT/7ysqvltL0fvvkXjj3E6rT3/zwru7\nuObiwTw9YTy7itJZfeJbtMrzZ+NqiUKtIWDcBALGTcBVUkzlxg1UbfyeyvXrqFy/Dk14BJZLphAw\n8WKU5t47DO2HGk7mULZqJdXbtoLXS9BVV2OdNv28+7k8Xj5Yk8WSu8ejlJTEBkQzP/k6oswiC5wg\nCD7ne8Ajgplepj77BCdffQmv00nwLbdhvXSq/70N6fmUVdUzc2yUf72KRk8jf0l/h6LaEmZGT2Va\n1CU9VHJBEDrD2MHB/n9HmcOJLrmWsIRK8jyZ7CvNYF9pBoOtSfzfqLsu+HeoLBYcNy4g8IrZlK9e\n1RnF7rdiwy0kRVlRKhSMDhnJN994mXFtSqccW213YJ87D9vVc6k9sJ/KDeup2b2L4g//TfHHH2Ia\neREBEyZiSB2OQt07Ern8UF3WIcq++hJnehoAmvAIgmbPwTxhYrPbNzR6+OeqDO6Yk4JKqSBlUCAP\n3TAchSSxIPk6NEr1gF5GQBCE9hPBTC9Sf/wYJ197GW9dHSG33ekbEnKWi5Ls/OWz/cwcGwWAx+vh\nH/vf51hVNmNDRnFN/KyeKLYgCF3owWvHolRKqJRXkFeTz8urVpAQcWZtGlmWL3hYkspiwXHD/M4q\nar90/w0jKS6uBqCwrBaPV8Zq9PWk1TW4WbvrJHMmxgDwQcZHJFrjGRU8vF2ptiWFAmPqMIypw3BX\nV1G9ZTOVG76nZucOanbuQGEwYh4zFvOEiegTEns8G5rs9eJMT6Psqy+pP3IYAH1iEoGzrsQ4bHiz\n5Tv9PdVqlFTW1bLvaBkjE33plUMCfX9PnUrM3RIEof1EMNNL1B09Qu7rr+Ctryf0jrsImOgbZ/zJ\n+qNMSg0lJMiAUafmkfkj/fsU1BaRWX6ElKAkFqZcL55mCUI/pD1rQqRDF8LVcbOZlhQB+FZU/vU7\n2/nVrWPQaVQsz/yUyoZKEgLjSLTGEWEKE9eFThRmM/L4wtH+12mHS8g6WQlAUW0xm/N2sDFvG18c\n/R+XRV/KxLAx7R4OqDIHEDjzCqyXXU5DTjbVWzZTtXULleu/o3L9d6iCbJjHTyBgwkS0EZGdWr/z\nkd1uqrdtpWzVlzTm5QFgHD6CoNlz0Ccmtbjfik3H0WtVXHpRKN/mbKAgdC2OsEXdVWxBEPo5Ecz0\nAnVZWeT+/lW8jY2E3nUPAeMn+N8z69Ws2HScO686d7JphCmMR0b9DLs+6JyUwIIg9D9qlYLpo87c\nwOaX1hLpMPnXmzpWkUOOM4e0kv0A6FU64i2x3Jg0t9snUvdXZ/eCjUiwEx/hWwQy2OBgivbHHKjd\nRVljFssP/ZeVx77m8phpTI+a3NLhWv09uuhB6KIHYb/+RuoyM6jaspmandsp/+pLyr/6Em1UFObx\nEzGPm4A6qOs+X29DA5Xfr6N89SrcZWWgVGKeeDFBs65sMaCqb3T7v5fD4mws376Fja5lFNYWYVIb\nKa+vIMLUcqpVQRCEthJ3wD2s9lAmub9/DdntJuyn96IZMZrN+wuYeCrt8owxkbjd3hb3jxSTJAVh\nwIoOMbPo2jNDzi6zzGdr8THGjFaRVXGUAyVZ7CvJ4LahP252f6/sFT03HaDXqvzzFwGSQyMYb4rD\nGgjf5mzgm+MbycorYbpvZDBHcisJCtARaNZSWleOJEGg1nreYYKSQoEhZQiGlCF4b74FZ/oeqrZs\nxrk3nYaPPqTk4/+gTx5MwPgJmEaPQWno2OKrp3mqqylfu4aKtWvwOp1IGg3WGTMJvPwK1DZ7i/uV\nVdWzZOlOfnv3BOrlWtaUfMYJYzpSrcTkiIlcHXcFRrWhxf0FQRDaQwQzPaj24AFy//A7ZI+HsHt+\nhnnUaBoaPXz6/VHMBjWpsTYUkoRGPTBWjRcEoWPGDA5mVJIDhUJifNhoVm/PocxbhV6lA2DzvgLK\nquuZMzGGencDT276LTEBUTwz8+EeLnn/MDz+zA3+3PjZlGRGM3XImd6Hj9cd4cqJgwg0a/k6+zu+\nz92MSWUi3jqImIBoogOiiLVEt5otTaHRYB4zDvOYcXhqaqjeuZ3qLZupyzhIXcZBit5finHESMxj\nxqE0meDsQEmSmrz2BVESSDTdzitz9NPdFKxeg9zYiMJoJOjquQROv6zFDGv/+fYw00ZFYLfoCQrQ\ncXFqKGXV9RhMcKD0EDEB0cxPupbogO4dGicIQv/Xo8FMzocf4bGHoYuN8110BxDn/n3k/fH3IMs4\n7rmPhvgUzPjGxz90wwhsAbom29e6atlXmsHo4BHtmlgqCMLAcvb6U5ePjUKWZf/rnKIaQm2+J+IV\nDZUoPToOlh3q9jIOFHdeObTJ6ykjwokJDQAgNiCazZnHwVpDWsl+/9DAqyOuY1ayb6jxweNlxIYH\n+Idr/ZDSZMJ66TSsl07DVVJM1dYtVG/d7E8c0FGqoCACL5+NZfIUFNqmk/P3Hi0l0Kwl0uFru6tq\nG0k/UuofBvmjS+P92/58zH2EGByiF1AQhC7Ro8FM9vv/9v9bHRyCLjbO919cHNqo6F6birKjynfu\nIu8PvwMg/P4H2CsFs+qTvTz5kzGolArCbL4hAuX1FaSV7Ce9eD9ZFUfxyl4CtRYSA+NbO7wgCILf\n2UOYbpye4A9uQo3BxFdfw+ihlp4q2oAz4dTwYYDxYaNJuWwYJp2aysZKjlfl8J+t2xkZlujf5q3P\n9/P07ePQaVR8nPUF6VllzBo+giGOOCzaAE4W1xBmM6BUKFDbHdjmXE3QlVfRkJNN7b69yG43wJmA\nVpaB0/8+/Zoz25y1nX1IEiQPQ1L5bhMqahqoa3D726fDJ8upcFUydoSBgtoi1DGFyKZQ4Nyel966\nkLMgCP1DjwYzKb96nMLd+6g/dpT6Y0ep3rqZ6q2bAZBUKrRR0ehiY9HFxqOLi0MdHNIrVka+UN76\nOmrS0ih8528gSYTd/yDGoamMl2UaXJ4mT1CXZ37K+txN/teDAqIYYR+KXW/riaILgtBPnH0N/ek1\nQ1vZUuhqAQbfcLJAnZVAnZWLrh7mf0+WZeZMjMFq0uCVvWzO206drp5/HdoPh3xzbUoLdCyZdRdB\nRl9vz7tfHeTmmUnoogehiYomv8RJxKmeE1mW8XjlJgsut8ZuN3E8pxzTqbuEvUdLST9Syn3zhrG/\nNJNvPe/ikTzsSD+zT1JjAjMGTemEv4wgCELb9Wgws0Vfj3bSYGyXTSRca0FVWkX9sSPUHfUFN/XZ\nJ6g/dhT4BgCFwegLbuLi0cXEorJYUOgNKI1GFHo9krJ3DL9yV1fRmJ9PY16u7//5eTTm5+MuLwNA\nodWyZfjVJEh2JuC7ubh0ZESTY0SawhgcmMgIx1CG2YcQqLP2QE0EQRCEniBJkn9NMQmJ30x6jGMV\n2WTXnOR4VTbHKrNRBdZg0ft6SmrqXGzPKObWWYORZZkTFXm8/J/dLF44kkavC2dDA3/59AB/vuc6\nwJdt7Df/3MGSuydQ2VDNmhPr2ZVVwNB4Ky6viyJnOfmFLl676gEALkp0+Dt1gnRWIk3hBBschBod\nhBiCCTE4cIiHbYIg9IBODWZkWebXv/41mZmZaDQalixZQlRUVIvbv5u2DJRu/2uFrMZuCOSRGxcR\nojayY18uSWonnpzj1B87St3RI9Tu30ft/n3NHk+h06EwGFAYjCgNBhQGw6n/G8/832hAoTeg0OmQ\n1GoktRqFRuP7t0qNpNH4hrcpla32AsmyjLus7FSgkucPWBry8/DW1JyzvdJqpSEqgZCkWMJnTedE\nST5rc7+iQBPCtQlXnrP9pIjxTIoY39qfWxAEQWin9rZTvYVepWeIPZkh9mTAV4+qxhr/HEqDTsVz\nd41HkiTK6yt4ZffvkQbDizvW+4+hiwsAfMGM2yOjUfn2rXfXsfbkOtDDRt/yMUhI6LU23B4vKqUC\nk17N5BG+7JlhxhB+Mfb/uqnmgiAIrevUYGbNmjU0NjaybNky0tLSeP7553nzzTdb3H6wagqJMRoq\nGispqy9nX04uTo0Tg0qPLMu8/VUWf3hoMtrkJLyyl//75nFscjRxVSpCK2TqSusJ0agYpHbgra2l\ntKicAMmNu7SExpN1HauMJIFajeJ0wKPWgEqFQqMBWaaxsAC5oaHJLrIkIdkCMcaPRLaH8MWhOm67\nZSqasDBKXY28tuYdUuLqOLb3Terdvn3l0nLmxs/u08PnBEEQ+or2tlO9lSRJWLRnMospJIlAs2+S\nvsvrZlL4eBSSArVChVqhRq1QYdacSbRj0qt5+vaxAATpAvn56PuQUKJXaVAp1MSGh1JV3rSNEwRB\n6I06NZjZuXMnkyf7FgcbMWIE+/Y134Ny2rM33kBxcbX/tXe4jOLUTb3H6+UnVySjPZWWuLaxAa3L\njsLqZbe6AnegG2JBrZD43dQH8Hplfv3St/ztl9OQJIm6xnqe+OZJtC4ZXaMXbaOMttGL3iVxY9QV\neOrr+WrDEWaNDkN2uXA1NLAnbw8aL6g8oPLKSC4vWtmFQ23E62qkprQCw6m/mMJu56CyjDKLgjKL\nijKLigqzEo1WzytTHsLrlXF9shddbCySJGFWSWDN42AZhJocDA1KYYQ9lVhLtAhkBEEQukl726m+\nKNhg56bBP2rz9mqlmljLoCY/06o0gAhmBEHo/To1mKmpqcF8Vg56lUqF1+tFoWjbhEPFWTf1SoWC\nS4afyc9v0up5bfbPAV/3eo3LSXGVE6P+1D4SPHXbWH9goFAquShkBvZADY3eRho8jeQUV2IOMhCU\nciVeWSYo+ATBF8cAUO9qYMP3bxBo1uCRvXhlmbLqOuwBBh4f9zAer5c/fryXB28YAYDH6+Gv371K\nqDUAg0pPkEqH5FUTaPA9+VIoJB64fri//DqVliWTnkCn1BEVZm8SxAmCIAjdo6PtlCAIgtC7SPLZ\nKbQ66IUXXmDkyJHMmjULgKlTp/Ldd9911uEFQRAEoUNEOyUIgtC/dOqjqFGjRrFu3ToA9uzZQ1JS\nUmceXhAEQRA6RLRTgiAI/Uun9sycnSUG4Pnnnyc2NrazDi8IgiAIHSLaKUEQhP6lU4MZQRAEQRAE\nQRCE7iJmPAqCIAiCIAiC0CeJYEYQBEEQBEEQhD5JBDOCIAiCIAiCIPRJ7V5n5uzJkxqNhiVLliDL\nMosXL0ahUJCYmMjTTz993n2ioqLIzs7ukv26QktlAfjiiy94//33WbZsWb+qd3PlcDqdPP3006hU\nKmJiYliyZEm/qvPZ0tLSeOWVV1i6dCkHDx7kueeeQ6lUotFoeOmllwgKIdv4DgAAB21JREFUCur3\n9S4rK+PJJ5+kuroaj8fDiy++6P/e95d6u91uHn/8cXJzc3G5XNx7770kJCT0+2tafybaKdFOiXZK\ntFP9qd6inToPuZ1Wr14tL168WJZlWU5LS5MXLVok33vvvfL27dtlWZblp556Sv76669b3GfPnj3y\nokWLZFmWu2y/rtBSWfbv3y/feuut8vz589u8T1+pd3Of9f333y+vX79elmVZfuSRR+Rvv/22U8re\nW+p82l//+lf5qquu8n+uCxculDMyMmRZluVly5bJzz//fKeUv7fXe/HixfJXX30ly7Isb9myRf7u\nu+86pfy9qd4ff/yx/Nvf/laWZVmurKyUp06dOiCuaf2ZaKdEOyXaKdFOdbT8vaneop1qXbuHme3c\nuZPJkycDMHz4cPbt28eBAwcYM2YMAFOmTGHz5s0A/PKXv6SgoKDJPiNGjGD//v0A7N+/v1P360rN\nlaWiooLf/e53PPHEE022Xbx4cb+od3OfdUpKCuXl5ciyjNPpRKVS9as6nzZo0CD+9Kc/+V+//vrr\nJCcnA74nJFqttkPl7yv13rVrFwUFBdx+++2sWLGC8ePHA/3r8549ezYPPvggAB6PB6VSOSCuaf2Z\naKdEOyXaKdFO9afPW7RTrWt3MFNTU4PZbPa/ViqVyGdldzYajVRXVwPw4osvEhoa2uw+Ho+n0/fr\nSj8siyRJLF68mMWLF6PX65uU6YUXXugX9W6uHBERESxZsoQ5c+ZQVlbGuHHjgP5T59NmzpyJUqn0\nv7bb7YDvovnBBx9w2223daj8faXeubm5WK1W3nnnHUJDQ3n77beB/vV56/V6DAYDNTU1PPjggzz8\n8MMD4prWn4l2yke0U6Kd6kj5+0q9RTvVf69pbdXuYMZkMuF0Ov2vvV4vCsWZwzidTgICAs67j1Kp\n7LL9usIPy1JRUUFubi6//vWveeSRRzhy5AjPP/98p5S/t9S7uXK89NJLfPDBB6xcuZJrrrmGF154\noVPK3lvq3JqVK1fyzDPP8PbbbxMYGNjkvf5ab6vVyrRp0wCYPn26/wnNaf2l3vn5+dx6663MmzeP\nOXPmDIhrWn8m2ikf0U6Jdups/bXeop3qv9e0tmp3MDNq1CjWrVsHwJ49e0hOTiYlJYVt27YBsH79\nekaPHt3qPklJSQAMGTKE7du3d/p+XeGHZRk3bhxffPEF7733Hq+99hoJCQk89thjnVL+3lLv5sph\nsVgwGo0AhISEUFVV1Sll7y11bslnn33G+++/z9KlS4mIiDjn/f5a79GjR/vLt337dhISEpq83x/q\nXVJSwp133smjjz7KvHnzAEhJSemS8vemevdnop0S7ZRop0Q7dVp/qLdop86jvZNsvF6v/NRTT8nz\n58+X58+fLx89elQ+duyYvHDhQnn+/Pny448/Lnu9XlmWZfkXv/iFnJ+f3+w+six3+n5dqaWyyLIs\nnzx5ssnEyv5S7+bKsXPnTnnBggXywoUL5TvuuEPOzc3tV3U+2+nP1ePxyOPGjZOvvfZaeeHChfIt\nt9wi/+EPf+j39ZZlWc7NzZVvv/12ecGCBfLdd98tV1VV9bt6P/fcc/KkSZPkW265xf/5ZmRk9Ptr\nWn8m2inRTol2SrRT/aneop1qnSTLZw2CEwRBEARBEARB6CPEopmCIAiCIAiCIPRJIpgRBEEQBEEQ\nBKFPEsGMIAiCIAiCIAh9kghmBEEQBEEQBEHok0QwIwiCIAiCIAhCnySCGUEQBEEQBEEQ+iQRzAhC\nM2pqarjvvvsoLi7mnnvu6eniCIIgCEITop0SBB8RzAhCMyoqKsjIyMDhcPDWW2/1dHEEQRAEoQnR\nTgmCj1g0UxCasWjRIjZs2MCll17KgQMHWLt2LY899hh6vZ6dO3dSXV3N448/zmeffUZmZiYzZszg\nl7/8JV6vl5deeolt27bh9XqZN28et956a09XRxAEQehnRDslCD6iZ0YQmvHkk08SHBzM448/jiRJ\n/p8XFxfz2Wef8cADD/DYY4/x7LPP8t///pcPP/yQmpoaPvzwQyRJ4pNPPuHDDz9kzZo17Ny5swdr\nIgiCIPRHop0SBB9VTxdAEHqzH3ZcTpkyBYDw8HCSkpIIDAwEwGq1UlVVxaZNm8jMzGTz5s0A1NXV\ncejQIUaPHt29BRcEQRAGBNFOCQOdCGYEoRVnP+0CUKvV/n8rlcpztvd6vTz66KNcdtllAJSXl2M0\nGru2kIIgCMKAJdopYaATw8wEoRkqlQqPx4Msy+c89WrO6W0mTJjA8uXLcbvdOJ1ObrrpJtLS0rq6\nuIIgCMIAI9opQfARPTOC0AybzUZYWBiPPfYYCsX5Y/7TT8YWLFjAiRMnmDdvHh6Ph+uvv56xY8d2\ndXEFQRCEAUa0U4LgI7KZCYIgCIIgCILQJ4lhZoIgCIIgCIIg9EkimBEEQRAEQRAEoU8SwYwgCIIg\nCIIgCH2SCGYEQRAEQRAEQeiTRDAjCIIgCIIgCEKfJIIZQRAEQRAEQRD6JBHMCIIgCIIgCILQJ4lg\nRhAEQRAEQRCEPun/A1rsNddykhZ+AAAAAElFTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import matplotlib.pyplot as plt\n", + "fig, ax = plt.subplots(1, 2, figsize=(14, 5))\n", + "by_time.ix['Weekday'].plot(ax=ax[0], title='Weekdays',\n", + " xticks=hourly_ticks, style=[':', '--', '-'])\n", + "by_time.ix['Weekend'].plot(ax=ax[1], title='Weekends',\n", + " xticks=hourly_ticks, style=[':', '--', '-']);" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The result is very interesting: we see a bimodal commute pattern during the work week, and a unimodal recreational pattern during the weekends.\n", + "It would be interesting to dig through this data in more detail, and examine the effect of weather, temperature, time of year, and other factors on people's commuting patterns; for further discussion, see my blog post [\"Is Seattle Really Seeing an Uptick In Cycling?\"](https://jakevdp.github.io/blog/2014/06/10/is-seattle-really-seeing-an-uptick-in-cycling/), which uses a subset of this data.\n", + "We will also revisit this dataset in the context of modeling in [In Depth: Linear Regression](05.06-Linear-Regression.ipynb)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "< [Vectorized String Operations](03.10-Working-With-Strings.ipynb) | [Contents](Index.ipynb) | [High-Performance Pandas: eval() and query()](03.12-Performance-Eval-and-Query.ipynb) >" + ] + } + ], + "metadata": { + "anaconda-cloud": {}, + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.4.3" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/pandas/03.12-Performance-Eval-and-Query.ipynb b/pandas/03.12-Performance-Eval-and-Query.ipynb new file mode 100644 index 0000000..1a9f5ed --- /dev/null +++ b/pandas/03.12-Performance-Eval-and-Query.ipynb @@ -0,0 +1,1147 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "\n", + "*This notebook contains an excerpt from the [Python Data Science Handbook](http://shop.oreilly.com/product/0636920034919.do) by Jake VanderPlas; the content is available [on GitHub](https://github.com/jakevdp/PythonDataScienceHandbook).*\n", + "\n", + "*The text is released under the [CC-BY-NC-ND license](https://creativecommons.org/licenses/by-nc-nd/3.0/us/legalcode), and code is released under the [MIT license](https://opensource.org/licenses/MIT). If you find this content useful, please consider supporting the work by [buying the book](http://shop.oreilly.com/product/0636920034919.do)!*\n", + "\n", + "*No changes were made to the contents of this notebook from the original.*" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "< [Working with Time Series](03.11-Working-with-Time-Series.ipynb) | [Contents](Index.ipynb) | [Further Resources](03.13-Further-Resources.ipynb) >" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# High-Performance Pandas: eval() and query()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "As we've already seen in previous sections, the power of the PyData stack is built upon the ability of NumPy and Pandas to push basic operations into C via an intuitive syntax: examples are vectorized/broadcasted operations in NumPy, and grouping-type operations in Pandas.\n", + "While these abstractions are efficient and effective for many common use cases, they often rely on the creation of temporary intermediate objects, which can cause undue overhead in computational time and memory use.\n", + "\n", + "As of version 0.13 (released January 2014), Pandas includes some experimental tools that allow you to directly access C-speed operations without costly allocation of intermediate arrays.\n", + "These are the ``eval()`` and ``query()`` functions, which rely on the [Numexpr](https://github.com/pydata/numexpr) package.\n", + "In this notebook we will walk through their use and give some rules-of-thumb about when you might think about using them." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Motivating ``query()`` and ``eval()``: Compound Expressions\n", + "\n", + "We've seen previously that NumPy and Pandas support fast vectorized operations; for example, when adding the elements of two arrays:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "100 loops, best of 3: 3.39 ms per loop\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "rng = np.random.RandomState(42)\n", + "x = rng.rand(1000000)\n", + "y = rng.rand(1000000)\n", + "%timeit x + y" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "As discussed in [Computation on NumPy Arrays: Universal Functions](02.03-Computation-on-arrays-ufuncs.ipynb), this is much faster than doing the addition via a Python loop or comprehension:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1 loop, best of 3: 266 ms per loop\n" + ] + } + ], + "source": [ + "%timeit np.fromiter((xi + yi for xi, yi in zip(x, y)), dtype=x.dtype, count=len(x))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "But this abstraction can become less efficient when computing compound expressions.\n", + "For example, consider the following expression:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "mask = (x > 0.5) & (y < 0.5)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Because NumPy evaluates each subexpression, this is roughly equivalent to the following:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "tmp1 = (x > 0.5)\n", + "tmp2 = (y < 0.5)\n", + "mask = tmp1 & tmp2" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In other words, *every intermediate step is explicitly allocated in memory*. If the ``x`` and ``y`` arrays are very large, this can lead to significant memory and computational overhead.\n", + "The Numexpr library gives you the ability to compute this type of compound expression element by element, without the need to allocate full intermediate arrays.\n", + "The [Numexpr documentation](https://github.com/pydata/numexpr) has more details, but for the time being it is sufficient to say that the library accepts a *string* giving the NumPy-style expression you'd like to compute:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import numexpr\n", + "mask_numexpr = numexpr.evaluate('(x > 0.5) & (y < 0.5)')\n", + "np.allclose(mask, mask_numexpr)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The benefit here is that Numexpr evaluates the expression in a way that does not use full-sized temporary arrays, and thus can be much more efficient than NumPy, especially for large arrays.\n", + "The Pandas ``eval()`` and ``query()`` tools that we will discuss here are conceptually similar, and depend on the Numexpr package." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## ``pandas.eval()`` for Efficient Operations\n", + "\n", + "The ``eval()`` function in Pandas uses string expressions to efficiently compute operations using ``DataFrame``s.\n", + "For example, consider the following ``DataFrame``s:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import pandas as pd\n", + "nrows, ncols = 100000, 100\n", + "rng = np.random.RandomState(42)\n", + "df1, df2, df3, df4 = (pd.DataFrame(rng.rand(nrows, ncols))\n", + " for i in range(4))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To compute the sum of all four ``DataFrame``s using the typical Pandas approach, we can just write the sum:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "10 loops, best of 3: 87.1 ms per loop\n" + ] + } + ], + "source": [ + "%timeit df1 + df2 + df3 + df4" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The same result can be computed via ``pd.eval`` by constructing the expression as a string:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "10 loops, best of 3: 42.2 ms per loop\n" + ] + } + ], + "source": [ + "%timeit pd.eval('df1 + df2 + df3 + df4')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The ``eval()`` version of this expression is about 50% faster (and uses much less memory), while giving the same result:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.allclose(df1 + df2 + df3 + df4,\n", + " pd.eval('df1 + df2 + df3 + df4'))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Operations supported by ``pd.eval()``\n", + "\n", + "As of Pandas v0.16, ``pd.eval()`` supports a wide range of operations.\n", + "To demonstrate these, we'll use the following integer ``DataFrame``s:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "df1, df2, df3, df4, df5 = (pd.DataFrame(rng.randint(0, 1000, (100, 3)))\n", + " for i in range(5))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Arithmetic operators\n", + "``pd.eval()`` supports all arithmetic operators. For example:" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "result1 = -df1 * df2 / (df3 + df4) - df5\n", + "result2 = pd.eval('-df1 * df2 / (df3 + df4) - df5')\n", + "np.allclose(result1, result2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Comparison operators\n", + "``pd.eval()`` supports all comparison operators, including chained expressions:" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "result1 = (df1 < df2) & (df2 <= df3) & (df3 != df4)\n", + "result2 = pd.eval('df1 < df2 <= df3 != df4')\n", + "np.allclose(result1, result2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Bitwise operators\n", + "``pd.eval()`` supports the ``&`` and ``|`` bitwise operators:" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "result1 = (df1 < 0.5) & (df2 < 0.5) | (df3 < df4)\n", + "result2 = pd.eval('(df1 < 0.5) & (df2 < 0.5) | (df3 < df4)')\n", + "np.allclose(result1, result2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In addition, it supports the use of the literal ``and`` and ``or`` in Boolean expressions:" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "result3 = pd.eval('(df1 < 0.5) and (df2 < 0.5) or (df3 < df4)')\n", + "np.allclose(result1, result3)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Object attributes and indices\n", + "\n", + "``pd.eval()`` supports access to object attributes via the ``obj.attr`` syntax, and indexes via the ``obj[index]`` syntax:" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "result1 = df2.T[0] + df3.iloc[1]\n", + "result2 = pd.eval('df2.T[0] + df3.iloc[1]')\n", + "np.allclose(result1, result2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Other operations\n", + "Other operations such as function calls, conditional statements, loops, and other more involved constructs are currently *not* implemented in ``pd.eval()``.\n", + "If you'd like to execute these more complicated types of expressions, you can use the Numexpr library itself." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## ``DataFrame.eval()`` for Column-Wise Operations\n", + "\n", + "Just as Pandas has a top-level ``pd.eval()`` function, ``DataFrame``s have an ``eval()`` method that works in similar ways.\n", + "The benefit of the ``eval()`` method is that columns can be referred to *by name*.\n", + "We'll use this labeled array as an example:" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ABC
00.3755060.4069390.069938
10.0690870.2356150.154374
20.6779450.4338390.652324
30.2640380.8080550.347197
40.5891610.2524180.557789
\n", + "
" + ], + "text/plain": [ + " A B C\n", + "0 0.375506 0.406939 0.069938\n", + "1 0.069087 0.235615 0.154374\n", + "2 0.677945 0.433839 0.652324\n", + "3 0.264038 0.808055 0.347197\n", + "4 0.589161 0.252418 0.557789" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df = pd.DataFrame(rng.rand(1000, 3), columns=['A', 'B', 'C'])\n", + "df.head()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Using ``pd.eval()`` as above, we can compute expressions with the three columns like this:" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "result1 = (df['A'] + df['B']) / (df['C'] - 1)\n", + "result2 = pd.eval(\"(df.A + df.B) / (df.C - 1)\")\n", + "np.allclose(result1, result2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The ``DataFrame.eval()`` method allows much more succinct evaluation of expressions with the columns:" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "result3 = df.eval('(A + B) / (C - 1)')\n", + "np.allclose(result1, result3)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Notice here that we treat *column names as variables* within the evaluated expression, and the result is what we would wish." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Assignment in DataFrame.eval()\n", + "\n", + "In addition to the options just discussed, ``DataFrame.eval()`` also allows assignment to any column.\n", + "Let's use the ``DataFrame`` from before, which has columns ``'A'``, ``'B'``, and ``'C'``:" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ABC
00.3755060.4069390.069938
10.0690870.2356150.154374
20.6779450.4338390.652324
30.2640380.8080550.347197
40.5891610.2524180.557789
\n", + "
" + ], + "text/plain": [ + " A B C\n", + "0 0.375506 0.406939 0.069938\n", + "1 0.069087 0.235615 0.154374\n", + "2 0.677945 0.433839 0.652324\n", + "3 0.264038 0.808055 0.347197\n", + "4 0.589161 0.252418 0.557789" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.head()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can use ``df.eval()`` to create a new column ``'D'`` and assign to it a value computed from the other columns:" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ABCD
00.3755060.4069390.06993811.187620
10.0690870.2356150.1543741.973796
20.6779450.4338390.6523241.704344
30.2640380.8080550.3471973.087857
40.5891610.2524180.5577891.508776
\n", + "
" + ], + "text/plain": [ + " A B C D\n", + "0 0.375506 0.406939 0.069938 11.187620\n", + "1 0.069087 0.235615 0.154374 1.973796\n", + "2 0.677945 0.433839 0.652324 1.704344\n", + "3 0.264038 0.808055 0.347197 3.087857\n", + "4 0.589161 0.252418 0.557789 1.508776" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.eval('D = (A + B) / C', inplace=True)\n", + "df.head()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In the same way, any existing column can be modified:" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ABCD
00.3755060.4069390.069938-0.449425
10.0690870.2356150.154374-1.078728
20.6779450.4338390.6523240.374209
30.2640380.8080550.347197-1.566886
40.5891610.2524180.5577890.603708
\n", + "
" + ], + "text/plain": [ + " A B C D\n", + "0 0.375506 0.406939 0.069938 -0.449425\n", + "1 0.069087 0.235615 0.154374 -1.078728\n", + "2 0.677945 0.433839 0.652324 0.374209\n", + "3 0.264038 0.808055 0.347197 -1.566886\n", + "4 0.589161 0.252418 0.557789 0.603708" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.eval('D = (A - B) / C', inplace=True)\n", + "df.head()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Local variables in DataFrame.eval()\n", + "\n", + "The ``DataFrame.eval()`` method supports an additional syntax that lets it work with local Python variables.\n", + "Consider the following:" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "column_mean = df.mean(1)\n", + "result1 = df['A'] + column_mean\n", + "result2 = df.eval('A + @column_mean')\n", + "np.allclose(result1, result2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The ``@`` character here marks a *variable name* rather than a *column name*, and lets you efficiently evaluate expressions involving the two \"namespaces\": the namespace of columns, and the namespace of Python objects.\n", + "Notice that this ``@`` character is only supported by the ``DataFrame.eval()`` *method*, not by the ``pandas.eval()`` *function*, because the ``pandas.eval()`` function only has access to the one (Python) namespace." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## DataFrame.query() Method\n", + "\n", + "The ``DataFrame`` has another method based on evaluated strings, called the ``query()`` method.\n", + "Consider the following:" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "result1 = df[(df.A < 0.5) & (df.B < 0.5)]\n", + "result2 = pd.eval('df[(df.A < 0.5) & (df.B < 0.5)]')\n", + "np.allclose(result1, result2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "As with the example used in our discussion of ``DataFrame.eval()``, this is an expression involving columns of the ``DataFrame``.\n", + "It cannot be expressed using the ``DataFrame.eval()`` syntax, however!\n", + "Instead, for this type of filtering operation, you can use the ``query()`` method:" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "result2 = df.query('A < 0.5 and B < 0.5')\n", + "np.allclose(result1, result2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In addition to being a more efficient computation, compared to the masking expression this is much easier to read and understand.\n", + "Note that the ``query()`` method also accepts the ``@`` flag to mark local variables:" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "Cmean = df['C'].mean()\n", + "result1 = df[(df.A < Cmean) & (df.B < Cmean)]\n", + "result2 = df.query('A < @Cmean and B < @Cmean')\n", + "np.allclose(result1, result2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Performance: When to Use These Functions\n", + "\n", + "When considering whether to use these functions, there are two considerations: *computation time* and *memory use*.\n", + "Memory use is the most predictable aspect. As already mentioned, every compound expression involving NumPy arrays or Pandas ``DataFrame``s will result in implicit creation of temporary arrays:\n", + "For example, this:" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "x = df[(df.A < 0.5) & (df.B < 0.5)]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Is roughly equivalent to this:" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "tmp1 = df.A < 0.5\n", + "tmp2 = df.B < 0.5\n", + "tmp3 = tmp1 & tmp2\n", + "x = df[tmp3]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If the size of the temporary ``DataFrame``s is significant compared to your available system memory (typically several gigabytes) then it's a good idea to use an ``eval()`` or ``query()`` expression.\n", + "You can check the approximate size of your array in bytes using this:" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "32000" + ] + }, + "execution_count": 28, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.values.nbytes" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "On the performance side, ``eval()`` can be faster even when you are not maxing-out your system memory.\n", + "The issue is how your temporary ``DataFrame``s compare to the size of the L1 or L2 CPU cache on your system (typically a few megabytes in 2016); if they are much bigger, then ``eval()`` can avoid some potentially slow movement of values between the different memory caches.\n", + "In practice, I find that the difference in computation time between the traditional methods and the ``eval``/``query`` method is usually not significant–if anything, the traditional method is faster for smaller arrays!\n", + "The benefit of ``eval``/``query`` is mainly in the saved memory, and the sometimes cleaner syntax they offer.\n", + "\n", + "We've covered most of the details of ``eval()`` and ``query()`` here; for more information on these, you can refer to the Pandas documentation.\n", + "In particular, different parsers and engines can be specified for running these queries; for details on this, see the discussion within the [\"Enhancing Performance\" section](http://pandas.pydata.org/pandas-docs/dev/enhancingperf.html)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "< [Working with Time Series](03.11-Working-with-Time-Series.ipynb) | [Contents](Index.ipynb) | [Further Resources](03.13-Further-Resources.ipynb) >" + ] + } + ], + "metadata": { + "anaconda-cloud": {}, + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.4.3" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/pandas/03.13-Further-Resources.ipynb b/pandas/03.13-Further-Resources.ipynb new file mode 100644 index 0000000..04117a8 --- /dev/null +++ b/pandas/03.13-Further-Resources.ipynb @@ -0,0 +1,76 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "\n", + "*This notebook contains an excerpt from the [Python Data Science Handbook](http://shop.oreilly.com/product/0636920034919.do) by Jake VanderPlas; the content is available [on GitHub](https://github.com/jakevdp/PythonDataScienceHandbook).*\n", + "\n", + "*The text is released under the [CC-BY-NC-ND license](https://creativecommons.org/licenses/by-nc-nd/3.0/us/legalcode), and code is released under the [MIT license](https://opensource.org/licenses/MIT). If you find this content useful, please consider supporting the work by [buying the book](http://shop.oreilly.com/product/0636920034919.do)!*\n", + "\n", + "*No changes were made to the contents of this notebook from the original.*" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "< [High-Performance Pandas: eval() and query()](03.12-Performance-Eval-and-Query.ipynb) | [Contents](Index.ipynb) | [Visualization with Matplotlib](04.00-Introduction-To-Matplotlib.ipynb) >" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Further Resources\n", + "\n", + "In this chapter, we've covered many of the basics of using Pandas effectively for data analysis.\n", + "Still, much has been omitted from our discussion.\n", + "To learn more about Pandas, I recommend the following resources:\n", + "\n", + "- [Pandas online documentation](http://pandas.pydata.org/): This is the go-to source for complete documentation of the package. While the examples in the documentation tend to be small generated datasets, the description of the options is complete and generally very useful for understanding the use of various functions.\n", + "\n", + "- [*Python for Data Analysis*](http://shop.oreilly.com/product/0636920023784.do) Written by Wes McKinney (the original creator of Pandas), this book contains much more detail on the Pandas package than we had room for in this chapter. In particular, he takes a deep dive into tools for time series, which were his bread and butter as a financial consultant. The book also has many entertaining examples of applying Pandas to gain insight from real-world datasets. Keep in mind, though, that the book is now several years old, and the Pandas package has quite a few new features that this book does not cover (but be on the lookout for a new edition in 2017).\n", + "\n", + "- [Stack Overflow](http://stackoverflow.com/questions/tagged/pandas): Pandas has so many users that any question you have has likely been asked and answered on Stack Overflow. Using Pandas is a case where some Google-Fu is your best friend. Simply go to your favorite search engine and type in the question, problem, or error you're coming across–more than likely you'll find your answer on a Stack Overflow page.\n", + "\n", + "- [Pandas on PyVideo](http://pyvideo.org/search?q=pandas): From PyCon to SciPy to PyData, many conferences have featured tutorials from Pandas developers and power users. The PyCon tutorials in particular tend to be given by very well-vetted presenters.\n", + "\n", + "Using these resources, combined with the walk-through given in this chapter, my hope is that you'll be poised to use Pandas to tackle any data analysis problem you come across!" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "< [High-Performance Pandas: eval() and query()](03.12-Performance-Eval-and-Query.ipynb) | [Contents](Index.ipynb) | [Visualization with Matplotlib](04.00-Introduction-To-Matplotlib.ipynb) >" + ] + } + ], + "metadata": { + "anaconda-cloud": {}, + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.4.3" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +}