{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "![](../docs/banner.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Chapter 9: Advanced Data Wrangling With Pandas" ] }, { "cell_type": "markdown", "metadata": { "toc": true }, "source": [ "

Chapter Outline

\n", "
\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Chapter Learning Objectives\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Manipulate strings in Pandas by accessing methods from the `Series.str` attribute.\n", "- Understand how to use regular expressions in Pandas for wrangling strings.\n", "- Differentiate between datetime object in Pandas such as `Timestamp`, `Timedelta`, `Period`, `DateOffset`.\n", "- Create these datetime objects with functions like `pd.Timestamp()`, `pd.Period()`, `pd.date_range()`, `pd.period_range()`.\n", "- Index a datetime index with partial string indexing.\n", "- Perform basic datetime operations like splitting a datetime into constituent parts (e.g., `year`, `weekday`, `second`, etc), apply offsets, change timezones, and resample with `.resample()`.\n", "- Make basic plots in Pandas by accessing the `.plot` attribute or importing functions from `pandas.plotting`." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 1. Working With Strings\n", "
" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import pandas as pd\n", "import numpy as np\n", "pd.set_option(\"display.max_rows\", 20)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Working with text data is common in data science. Luckily, Pandas Series and Index objects are equipped with a set of string processing methods which we'll explore here." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### String dtype" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "String data is represented in pandas using the `object` dtype, which is a generic dtype for representing mixed data or data of unknown size. It would be better to have a dedicated dtype and Pandas has just introduced this: the `StringDtype`. `object` remains the default dtype for strings however, as Pandas looks to continue testing and improving the `string` dtype. You can read more about the `StringDtype` in the [Pandas documentation here](https://pandas.pydata.org/pandas-docs/stable/user_guide/text.html#text-data-types)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### String Methods" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We've seen how libraries like NumPy and Pandas can vectorise operations for increased speed and useability:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([ 2, 4, 6, 8, 10])" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x = np.array([1, 2, 3, 4, 5])\n", "x * 2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This is not the case for arrays of strings however:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "tags": [ "raises-exception" ] }, "outputs": [ { "ename": "AttributeError", "evalue": "'numpy.ndarray' object has no attribute 'upper'", "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[0mx\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0marray\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'Tom'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'Mike'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'Tiffany'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'Joel'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'Varada'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mx\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mupper\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mAttributeError\u001b[0m: 'numpy.ndarray' object has no attribute 'upper'" ] } ], "source": [ "x = np.array(['Tom', 'Mike', 'Tiffany', 'Joel', 'Varada'])\n", "x.upper()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Instead, you would have to operate on each string object one at a time, using a loop for example:" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['TOM', 'MIKE', 'TIFFANY', 'JOEL', 'VARADA']" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[name.upper() for name in x]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "But even this will fail if your array contains a missing value:" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "tags": [ "raises-exception" ] }, "outputs": [ { "ename": "AttributeError", "evalue": "'NoneType' object has no attribute 'upper'", "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[0mx\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0marray\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'Tom'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'Mike'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'Tiffany'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'Joel'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'Varada'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\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[0mname\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mupper\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mname\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mx\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\u001b[0m in \u001b[0;36m\u001b[0;34m(.0)\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0mx\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0marray\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'Tom'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'Mike'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'Tiffany'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'Joel'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'Varada'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\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[0mname\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mupper\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mname\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m]\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 'upper'" ] } ], "source": [ "x = np.array(['Tom', 'Mike', None, 'Tiffany', 'Joel', 'Varada'])\n", "[name.upper() for name in x]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Pandas addresses both of these issues (vectorization and missing values) with its string methods. String methods can be accessed by the `.str` attribute of Pandas Series and Index objects. Pretty much all built-in string operations (`.upper()`, `.lower()`, `.split()`, etc) and more are available." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0 Tom\n", "1 Mike\n", "2 None\n", "3 Tiffany\n", "4 Joel\n", "5 Varada\n", "dtype: object" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s = pd.Series(x)\n", "s" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0 TOM\n", "1 MIKE\n", "2 None\n", "3 TIFFANY\n", "4 JOEL\n", "5 VARADA\n", "dtype: object" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s.str.upper()" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
01
0TomNone
1MikeNone
2NoneNone
3Tiany
4JoelNone
5VaradaNone
\n", "
" ], "text/plain": [ " 0 1\n", "0 Tom None\n", "1 Mike None\n", "2 None None\n", "3 Ti any\n", "4 Joel None\n", "5 Varada None" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s.str.split(\"ff\", expand=True)" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0 3.0\n", "1 4.0\n", "2 NaN\n", "3 7.0\n", "4 4.0\n", "5 6.0\n", "dtype: float64" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s.str.len()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can also operate on Index objects (i.e., index or column labels):" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
Measured Featurerecorded featurePredictedFeature
ROW00.2001120.7907220.655438
ROW10.8663120.9410670.179676
ROW20.4783500.8447120.983463
ROW30.0281430.1204130.396831
ROW40.9414550.5260840.731475
\n", "
" ], "text/plain": [ " Measured Feature recorded feature PredictedFeature\n", "ROW0 0.200112 0.790722 0.655438\n", "ROW1 0.866312 0.941067 0.179676\n", "ROW2 0.478350 0.844712 0.983463\n", "ROW3 0.028143 0.120413 0.396831\n", "ROW4 0.941455 0.526084 0.731475" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df = pd.DataFrame(np.random.rand(5, 3),\n", " columns = ['Measured Feature', 'recorded feature', 'PredictedFeature'],\n", " index = [f\"ROW{_}\" for _ in range(5)])\n", "df" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "pandas.core.indexes.base.Index" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "type(df.columns)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's clean up those labels by:\n", "1. Removing the word \"feature\" and \"Feature\"\n", "2. Lowercase the \"ROW\" and add an underscore between the digit and letters" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [], "source": [ "df.columns = df.columns.str.capitalize().str.replace(\"feature\", \"\").str.strip()" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [], "source": [ "df.index = df.index.str.lower().str.replace(\"w\", \"w_\")" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
MeasuredRecordedPredicted
row_00.2001120.7907220.655438
row_10.8663120.9410670.179676
row_20.4783500.8447120.983463
row_30.0281430.1204130.396831
row_40.9414550.5260840.731475
\n", "
" ], "text/plain": [ " Measured Recorded Predicted\n", "row_0 0.200112 0.790722 0.655438\n", "row_1 0.866312 0.941067 0.179676\n", "row_2 0.478350 0.844712 0.983463\n", "row_3 0.028143 0.120413 0.396831\n", "row_4 0.941455 0.526084 0.731475" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Great that worked! There are so many string operations you can use in Pandas. Here's a full list of all the string methods available in Pandas that I pulled from the documentation:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "| Method | Description |\n", "| -------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |\n", "| `Series.str.cat` | Concatenate strings |\n", "| `Series.str.split` | Split strings on delimiter |\n", "| `Series.str.rsplit` | Split strings on delimiter working from the end of the string |\n", "| `Series.str.get` | Index into each element (retrieve i-th element) |\n", "| `Series.str.join` | Join strings in each element of the Series with passed separator |\n", "| `Series.str.get_dummies` | Split strings on the delimiter returning DataFrame of dummy variables |\n", "| `Series.str.contains` | Return boolean array if each string contains pattern/regex |\n", "| `Series.str.replace` | Replace occurrences of pattern/regex/string with some other string or the return value of a callable given the occurrence |\n", "| `Series.str.repeat` | Duplicate values (`s.str.repeat(3)` equivalent to `x * 3`) |\n", "| `Series.str.pad` | \"Add whitespace to left, right, or both sides of strings\" |\n", "| `Series.str.center` | Equivalent to `str.center` |\n", "| `Series.str.ljust` | Equivalent to `str.ljust` |\n", "| `Series.str.rjust` | Equivalent to `str.rjust` |\n", "| `Series.str.zfill` | Equivalent to `str.zfill` |\n", "| `Series.str.wrap` | Split long strings into lines with length less than a given width |\n", "| `Series.str.slice` | Slice each string in the Series |\n", "| `Series.str.slice_replace` | Replace slice in each string with passed value |\n", "| `Series.str.count` | Count occurrences of pattern |\n", "| `Series.str.startswith` | Equivalent to `str.startswith(pat)` for each element |\n", "| `Series.str.endswith` | Equivalent to `str.endswith(pat)` for each element |\n", "| `Series.str.findall` | Compute list of all occurrences of pattern/regex for each string |\n", "| `Series.str.match` | \"Call `re.match` on each element, returning matched groups as list\" |\n", "| `Series.str.extract` | \"Call `re.search` on each element, returning DataFrame with one row for each element and one column for each regex capture group\" |\n", "| `Series.str.extractall` | \"Call `re.findall` on each element, returning DataFrame with one row for each match and one column for each regex capture group\" |\n", "| `Series.str.len` | Compute string lengths |\n", "| `Series.str.strip` | Equivalent to `str.strip` |\n", "| `Series.str.rstrip` | Equivalent to `str.rstrip` |\n", "| `Series.str.lstrip` | Equivalent to `str.lstrip` |\n", "| `Series.str.partition` | Equivalent to `str.partition` |\n", "| `Series.str.rpartition` | Equivalent to `str.rpartition` |\n", "| `Series.str.lower` | Equivalent to `str.lower` |\n", "| `Series.str.casefold` | Equivalent to `str.casefold` |\n", "| `Series.str.upper` | Equivalent to `str.upper` |\n", "| `Series.str.find` | Equivalent to `str.find` |\n", "| `Series.str.rfind` | Equivalent to `str.rfind` |\n", "| `Series.str.index` | Equivalent to `str.index` |\n", "| `Series.str.rindex` | Equivalent to `str.rindex` |\n", "| `Series.str.capitalize` | Equivalent to `str.capitalize` |\n", "| `Series.str.swapcase` | Equivalent to `str.swapcase` |\n", "| `Series.str.normalize` | Return Unicode normal form. Equivalent to `unicodedata.normalize` |\n", "| `Series.str.translate` | Equivalent to `str.translate` |\n", "| `Series.str.isalnum` | Equivalent to `str.isalnum` |\n", "| `Series.str.isalpha` | Equivalent to `str.isalpha` |\n", "| `Series.str.isdigit` | Equivalent to `str.isdigit` |\n", "| `Series.str.isspace` | Equivalent to `str.isspace` |\n", "| `Series.str.islower` | Equivalent to `str.islower` |\n", "| `Series.str.isupper` | Equivalent to `str.isupper` |\n", "| `Series.str.istitle` | Equivalent to `str.istitle` |\n", "| `Series.str.isnumeric` | Equivalent to `str.isnumeric` |\n", "| `Series.str.isdecimal` | Equivalent to `str.isdecimal` |" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "I will also mention that I often use the dataframe method `df.replace()` to do string replacements:" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
col1col2
0replace me1
1b99999
2c3
\n", "
" ], "text/plain": [ " col1 col2\n", "0 replace me 1\n", "1 b 99999\n", "2 c 3" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df = pd.DataFrame({'col1': ['replace me', 'b', 'c'],\n", " 'col2': [1, 99999, 3]})\n", "df" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
col1col2
0a1
1b2
2c3
\n", "
" ], "text/plain": [ " col1 col2\n", "0 a 1\n", "1 b 2\n", "2 c 3" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.replace({'replace me': 'a',\n", " 99999: 2})" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Regular Expressions" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A regular expression (regex) is a sequence of characters that defines a search pattern. For more complex string operations, you'll definitely want to use regex. [Here's a great cheatsheet](https://www.rexegg.com/regex-quickstart.html) of regular expression syntax. I am self-admittedly not a regex expert, I usually jump over to [RegExr.com](https://regexr.com/) and play around until I find the expression I want. Many Pandas string functions accept regular expressions as input, these are the ones I use most often:\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": [ "For example, we can easily find all names in our Series that start and end with a consonant:" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0 Tom\n", "1 Mike\n", "2 None\n", "3 Tiffany\n", "4 Joel\n", "5 Varada\n", "dtype: object" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s = pd.Series(['Tom', 'Mike', None, 'Tiffany', 'Joel', 'Varada'])\n", "s" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0 [Tom]\n", "1 []\n", "2 None\n", "3 [Tiffany]\n", "4 [Joel]\n", "5 []\n", "dtype: object" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s.str.findall(r'^[^AEIOU].*[^aeiou]$')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's break down that regex:\n", "\n", "|Part|Description|\n", "|---|---|\n", "|`^`|Specifies the start of a string|\n", "|`[^AEIOU]`|Square brackets match a single character. When `^` is used inside square brackets it means \"not\", so we are are saying, \"the first character of the string should not be A, E, I, O, or U (i.e., a vowel)\"|\n", "|`.*`|`.` matches any character and `*` means \"0 or more time\", this is basically saying that we can have any number of characters in the middle of our string|\n", "|`[^aeiou]$`| `$` matches the end of the string, so we are saying, we don't want the last character to be a lowercase vowel|" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Regex can do some truly magical things so keep it in mind when you're doing complicated text wrangling. Let's see one more example on the cycling dataset:" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
NameTypeTimeDistanceComments
Date
10 Sep 2019, 00:13:04Afternoon RideRide208412.62Rain
10 Sep 2019, 13:52:18Morning RideRide253113.03rain
11 Sep 2019, 00:23:50Afternoon RideRide186312.52Wet road but nice weather
11 Sep 2019, 14:06:19Morning RideRide219212.84Stopped for photo of sunrise
12 Sep 2019, 00:28:05Afternoon RideRide189112.48Tired by the end of the week
..................
4 Oct 2019, 01:08:08Afternoon RideRide187012.63Very tired, riding into the wind
9 Oct 2019, 13:55:40Morning RideRide214912.70Really cold! But feeling good
10 Oct 2019, 00:10:31Afternoon RideRide184112.59Feeling good after a holiday break!
10 Oct 2019, 13:47:14Morning RideRide246312.79Stopped for photo of sunrise
11 Oct 2019, 00:16:57Afternoon RideRide184311.79Bike feeling tight, needs an oil and pump
\n", "

33 rows × 5 columns

\n", "
" ], "text/plain": [ " Name Type Time Distance \\\n", "Date \n", "10 Sep 2019, 00:13:04 Afternoon Ride Ride 2084 12.62 \n", "10 Sep 2019, 13:52:18 Morning Ride Ride 2531 13.03 \n", "11 Sep 2019, 00:23:50 Afternoon Ride Ride 1863 12.52 \n", "11 Sep 2019, 14:06:19 Morning Ride Ride 2192 12.84 \n", "12 Sep 2019, 00:28:05 Afternoon Ride Ride 1891 12.48 \n", "... ... ... ... ... \n", "4 Oct 2019, 01:08:08 Afternoon Ride Ride 1870 12.63 \n", "9 Oct 2019, 13:55:40 Morning Ride Ride 2149 12.70 \n", "10 Oct 2019, 00:10:31 Afternoon Ride Ride 1841 12.59 \n", "10 Oct 2019, 13:47:14 Morning Ride Ride 2463 12.79 \n", "11 Oct 2019, 00:16:57 Afternoon Ride Ride 1843 11.79 \n", "\n", " Comments \n", "Date \n", "10 Sep 2019, 00:13:04 Rain \n", "10 Sep 2019, 13:52:18 rain \n", "11 Sep 2019, 00:23:50 Wet road but nice weather \n", "11 Sep 2019, 14:06:19 Stopped for photo of sunrise \n", "12 Sep 2019, 00:28:05 Tired by the end of the week \n", "... ... \n", "4 Oct 2019, 01:08:08 Very tired, riding into the wind \n", "9 Oct 2019, 13:55:40 Really cold! But feeling good \n", "10 Oct 2019, 00:10:31 Feeling good after a holiday break! \n", "10 Oct 2019, 13:47:14 Stopped for photo of sunrise \n", "11 Oct 2019, 00:16:57 Bike feeling tight, needs an oil and pump \n", "\n", "[33 rows x 5 columns]" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df = pd.read_csv('data/cycling_data.csv', index_col=0)\n", "df" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We could find all the comments that contains the string \"Rain\" or \"rain\":" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
NameTypeTimeDistanceComments
Date
10 Sep 2019, 00:13:04Afternoon RideRide208412.62Rain
10 Sep 2019, 13:52:18Morning RideRide253113.03rain
17 Sep 2019, 13:43:34Morning RideRide228512.60Raining
18 Sep 2019, 13:49:53Morning RideRide290314.57Raining today
26 Sep 2019, 00:13:33Afternoon RideRide186012.52raining
\n", "
" ], "text/plain": [ " Name Type Time Distance Comments\n", "Date \n", "10 Sep 2019, 00:13:04 Afternoon Ride Ride 2084 12.62 Rain\n", "10 Sep 2019, 13:52:18 Morning Ride Ride 2531 13.03 rain\n", "17 Sep 2019, 13:43:34 Morning Ride Ride 2285 12.60 Raining\n", "18 Sep 2019, 13:49:53 Morning Ride Ride 2903 14.57 Raining today\n", "26 Sep 2019, 00:13:33 Afternoon Ride Ride 1860 12.52 raining" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.loc[df['Comments'].str.contains(r\"[Rr]ain\")]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If we didn't want to include \"Raining\" or \"raining\", we could do:" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
NameTypeTimeDistanceComments
Date
10 Sep 2019, 00:13:04Afternoon RideRide208412.62Rain
10 Sep 2019, 13:52:18Morning RideRide253113.03rain
\n", "
" ], "text/plain": [ " Name Type Time Distance Comments\n", "Date \n", "10 Sep 2019, 00:13:04 Afternoon Ride Ride 2084 12.62 Rain\n", "10 Sep 2019, 13:52:18 Morning Ride Ride 2531 13.03 rain" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.loc[df['Comments'].str.contains(r\"^[Rr]ain$\")]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can even split strings and separate them into new columns, for example, based on punctuation:" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
01
Date
10 Sep 2019, 00:13:04RainNone
10 Sep 2019, 13:52:18rainNone
11 Sep 2019, 00:23:50Wet road but nice weatherNone
11 Sep 2019, 14:06:19Stopped for photo of sunriseNone
12 Sep 2019, 00:28:05Tired by the end of the weekNone
.........
4 Oct 2019, 01:08:08Very tiredriding into the wind
9 Oct 2019, 13:55:40Really coldBut feeling good
10 Oct 2019, 00:10:31Feeling good after a holiday break
10 Oct 2019, 13:47:14Stopped for photo of sunriseNone
11 Oct 2019, 00:16:57Bike feeling tightneeds an oil and pump
\n", "

33 rows × 2 columns

\n", "
" ], "text/plain": [ " 0 \\\n", "Date \n", "10 Sep 2019, 00:13:04 Rain \n", "10 Sep 2019, 13:52:18 rain \n", "11 Sep 2019, 00:23:50 Wet road but nice weather \n", "11 Sep 2019, 14:06:19 Stopped for photo of sunrise \n", "12 Sep 2019, 00:28:05 Tired by the end of the week \n", "... ... \n", "4 Oct 2019, 01:08:08 Very tired \n", "9 Oct 2019, 13:55:40 Really cold \n", "10 Oct 2019, 00:10:31 Feeling good after a holiday break \n", "10 Oct 2019, 13:47:14 Stopped for photo of sunrise \n", "11 Oct 2019, 00:16:57 Bike feeling tight \n", "\n", " 1 \n", "Date \n", "10 Sep 2019, 00:13:04 None \n", "10 Sep 2019, 13:52:18 None \n", "11 Sep 2019, 00:23:50 None \n", "11 Sep 2019, 14:06:19 None \n", "12 Sep 2019, 00:28:05 None \n", "... ... \n", "4 Oct 2019, 01:08:08 riding into the wind \n", "9 Oct 2019, 13:55:40 But feeling good \n", "10 Oct 2019, 00:10:31 \n", "10 Oct 2019, 13:47:14 None \n", "11 Oct 2019, 00:16:57 needs an oil and pump \n", "\n", "[33 rows x 2 columns]" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df['Comments'].str.split(r\"[.,!]\", expand=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "My point being here that you can pretty much do anything your heart desires!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 2. Working With Datetimes\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Just like with strings, Pandas has extensive functionality for working with time series data." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Datetime dtype and Motivation for Using Pandas" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Python has built-in support for datetime format, that is, an object that contains time and date information, in the `datetime` module." ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [], "source": [ "from datetime import datetime, timedelta" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "datetime.datetime(2005, 7, 9, 13, 54)" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "date = datetime(year=2005, month=7, day=9, hour=13, minute=54)\n", "date" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can also parse directly from a string, see [format codes here](https://docs.python.org/3/library/datetime.html#strftime-and-strptime-format-codes):" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "datetime.datetime(2005, 7, 9, 13, 54)" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "date = datetime.strptime(\"July 9 2005, 13:54\", \"%B %d %Y, %H:%M\")\n", "date" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can then extract specific information from our data:" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Year: 2005\n", "Month: July\n", "Day: 09\n", "Day name: Saturday\n", "Day of year: 190\n", "Time of day: PM\n" ] } ], "source": [ "print(f\"Year: {date.strftime('%Y')}\")\n", "print(f\"Month: {date.strftime('%B')}\")\n", "print(f\"Day: {date.strftime('%d')}\")\n", "print(f\"Day name: {date.strftime('%A')}\")\n", "print(f\"Day of year: {date.strftime('%j')}\")\n", "print(f\"Time of day: {date.strftime('%p')}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And perform basic operations, like adding a week:" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "datetime.datetime(2005, 7, 16, 13, 54)" ] }, "execution_count": 27, "metadata": {}, "output_type": "execute_result" } ], "source": [ "date + timedelta(days=7)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "But as with strings, working with arrays of datetimes in Python can be difficult and inefficient. NumPy, therefore included a new datetime object to work more effectively with dates:" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array(['2020-07-09', '2020-08-10'], dtype='datetime64[D]')" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dates = np.array([\"2020-07-09\", \"2020-08-10\"], dtype=\"datetime64\")\n", "dates" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can create arrays using other built-in functions like `np.arange()` too:" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array(['2020-07', '2020-08', '2020-09', '2020-10', '2020-11'],\n", " dtype='datetime64[M]')" ] }, "execution_count": 29, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dates = np.arange(\"2020-07\", \"2020-12\", dtype='datetime64[M]')\n", "dates" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now we can easily do operations on arrays of time. You can check out all the datetime units and their format in the documentation [here](https://numpy.org/doc/stable/reference/arrays.datetime.html#datetime-units)." ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array(['2020-09', '2020-10', '2020-11', '2020-12', '2021-01'],\n", " dtype='datetime64[M]')" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dates + np.timedelta64(2, 'M')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "But while numpy helps bring datetimes into the array world, it's missing a lot of functionality that we would commonly want/need for wrangling tasks. This is where Pandas comes in. Pandas consolidates and extends functionality from the `datetime` module, `numpy`, and other libraries like `scikits.timeseries` into a single place. Pandas provides 4 key datetime objects which we'll explore in the following sections:\n", "1. Timestamp (like np.datetime64)\n", "2. Timedelta (like np.timedelta64)\n", "3. Period (custom object for regular ranges of datetimes)\n", "4. DateOffset (custom object like timedelta but factoring in calendar rules)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Creating Datetimes" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### From scratch" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Most commonly you'll want to:\n", "1. Create a single point in time with `pd.Timestamp()`, e.g., `2005-07-09 00:00:00`\n", "2. Create a span of time with `pd.Period()`, e.g., `2020 Jan`\n", "3. Create an array of datetimes with `pd.date_range()` or `pd.period_range()`" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2005-07-09 00:00:00\n", "2005-07-09 00:00:00\n", "2005-07-09 00:00:00\n" ] } ], "source": [ "print(pd.Timestamp('2005-07-09')) # parsed from string\n", "print(pd.Timestamp(year=2005, month=7, day=9)) # pass data directly\n", "print(pd.Timestamp(datetime(year=2005, month=7, day=9))) # from datetime object" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The above is a specific point in time. Below, we can use `pd.Period()` to specify a span of time (like a day):" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2005-07-09\n", "2005-07-09 00:00:00\n", "2005-07-09 23:59:59.999999999\n" ] } ], "source": [ "span = pd.Period('2005-07-09')\n", "print(span)\n", "print(span.start_time)\n", "print(span.end_time)" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Point: 2005-07-09 12:00:00\n", " Span: 2005-07-09\n", "Point in span? True\n" ] } ], "source": [ "point = pd.Timestamp('2005-07-09 12:00')\n", "span = pd.Period('2005-07-09')\n", "print(f\"Point: {point}\")\n", "print(f\" Span: {span}\")\n", "print(f\"Point in span? {span.start_time < point < span.end_time}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Often, you'll want to create arrays of datetimes, not just single values. Arrays of datetimes are of the class `DatetimeIndex`/`PeriodIndex`/`TimedeltaIndex`:" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "DatetimeIndex(['2020-09-01 12:00:00', '2020-09-02 12:00:00',\n", " '2020-09-03 12:00:00', '2020-09-04 12:00:00',\n", " '2020-09-05 12:00:00', '2020-09-06 12:00:00',\n", " '2020-09-07 12:00:00', '2020-09-08 12:00:00',\n", " '2020-09-09 12:00:00', '2020-09-10 12:00:00',\n", " '2020-09-11 12:00:00'],\n", " dtype='datetime64[ns]', freq='D')" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pd.date_range('2020-09-01 12:00',\n", " '2020-09-11 12:00',\n", " freq='D')" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "PeriodIndex(['2020-09-01', '2020-09-02', '2020-09-03', '2020-09-04',\n", " '2020-09-05', '2020-09-06', '2020-09-07', '2020-09-08',\n", " '2020-09-09', '2020-09-10', '2020-09-11'],\n", " dtype='period[D]', freq='D')" ] }, "execution_count": 35, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pd.period_range('2020-09-01',\n", " '2020-09-11',\n", " freq='D')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can use `Timedelta` objects to perform temporal operations like adding or subtracting time:" ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "DatetimeIndex(['2020-09-01 13:30:00', '2020-09-02 13:30:00',\n", " '2020-09-03 13:30:00', '2020-09-04 13:30:00',\n", " '2020-09-05 13:30:00', '2020-09-06 13:30:00',\n", " '2020-09-07 13:30:00', '2020-09-08 13:30:00',\n", " '2020-09-09 13:30:00', '2020-09-10 13:30:00',\n", " '2020-09-11 13:30:00'],\n", " dtype='datetime64[ns]', freq='D')" ] }, "execution_count": 36, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pd.date_range('2020-09-01 12:00', '2020-09-11 12:00', freq='D') + pd.Timedelta('1.5 hour')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Finally, Pandas represents missing datetimes with `NaT`, which is just like `np.nan`:" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "NaT" ] }, "execution_count": 37, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pd.Timestamp(pd.NaT)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### By converting existing data" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "It's fairly common to have an array of dates as strings. We can use `pd.to_datetime()` to convert these to datetime:" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['July 9, 2020', 'August 1, 2020', 'August 28, 2020']" ] }, "execution_count": 38, "metadata": {}, "output_type": "execute_result" } ], "source": [ "string_dates = ['July 9, 2020', 'August 1, 2020', 'August 28, 2020']\n", "string_dates" ] }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "DatetimeIndex(['2020-07-09', '2020-08-01', '2020-08-28'], dtype='datetime64[ns]', freq=None)" ] }, "execution_count": 39, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pd.to_datetime(string_dates)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For more complex datetime format, use the `format` argument (see [Python Format Codes](https://docs.python.org/3/library/datetime.html#strftime-and-strptime-format-codes) for help):" ] }, { "cell_type": "code", "execution_count": 40, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "DatetimeIndex(['2020-07-09', '2020-08-01', '2020-08-28'], dtype='datetime64[ns]', freq=None)" ] }, "execution_count": 40, "metadata": {}, "output_type": "execute_result" } ], "source": [ "string_dates = ['2020 9 July', '2020 1 August', '2020 28 August']\n", "pd.to_datetime(string_dates, format=\"%Y %d %B\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Or use a dictionary:" ] }, { "cell_type": "code", "execution_count": 41, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0 2020-07-09\n", "1 2020-08-01\n", "2 2020-08-28\n", "dtype: datetime64[ns]" ] }, "execution_count": 41, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dict_dates = pd.to_datetime({\"year\": [2020, 2020, 2020],\n", " \"month\": [7, 8, 8],\n", " \"day\": [9, 1, 28]}) # note this is a series, not an index!\n", "dict_dates" ] }, { "cell_type": "code", "execution_count": 42, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "DatetimeIndex(['2020-07-09', '2020-08-01', '2020-08-28'], dtype='datetime64[ns]', freq=None)" ] }, "execution_count": 42, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pd.Index(dict_dates)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### By reading directly from an external source" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's practice by reading in our favourite cycling dataset:" ] }, { "cell_type": "code", "execution_count": 43, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
NameTypeTimeDistanceComments
Date
10 Sep 2019, 00:13:04Afternoon RideRide208412.62Rain
10 Sep 2019, 13:52:18Morning RideRide253113.03rain
11 Sep 2019, 00:23:50Afternoon RideRide186312.52Wet road but nice weather
11 Sep 2019, 14:06:19Morning RideRide219212.84Stopped for photo of sunrise
12 Sep 2019, 00:28:05Afternoon RideRide189112.48Tired by the end of the week
..................
4 Oct 2019, 01:08:08Afternoon RideRide187012.63Very tired, riding into the wind
9 Oct 2019, 13:55:40Morning RideRide214912.70Really cold! But feeling good
10 Oct 2019, 00:10:31Afternoon RideRide184112.59Feeling good after a holiday break!
10 Oct 2019, 13:47:14Morning RideRide246312.79Stopped for photo of sunrise
11 Oct 2019, 00:16:57Afternoon RideRide184311.79Bike feeling tight, needs an oil and pump
\n", "

33 rows × 5 columns

\n", "
" ], "text/plain": [ " Name Type Time Distance \\\n", "Date \n", "10 Sep 2019, 00:13:04 Afternoon Ride Ride 2084 12.62 \n", "10 Sep 2019, 13:52:18 Morning Ride Ride 2531 13.03 \n", "11 Sep 2019, 00:23:50 Afternoon Ride Ride 1863 12.52 \n", "11 Sep 2019, 14:06:19 Morning Ride Ride 2192 12.84 \n", "12 Sep 2019, 00:28:05 Afternoon Ride Ride 1891 12.48 \n", "... ... ... ... ... \n", "4 Oct 2019, 01:08:08 Afternoon Ride Ride 1870 12.63 \n", "9 Oct 2019, 13:55:40 Morning Ride Ride 2149 12.70 \n", "10 Oct 2019, 00:10:31 Afternoon Ride Ride 1841 12.59 \n", "10 Oct 2019, 13:47:14 Morning Ride Ride 2463 12.79 \n", "11 Oct 2019, 00:16:57 Afternoon Ride Ride 1843 11.79 \n", "\n", " Comments \n", "Date \n", "10 Sep 2019, 00:13:04 Rain \n", "10 Sep 2019, 13:52:18 rain \n", "11 Sep 2019, 00:23:50 Wet road but nice weather \n", "11 Sep 2019, 14:06:19 Stopped for photo of sunrise \n", "12 Sep 2019, 00:28:05 Tired by the end of the week \n", "... ... \n", "4 Oct 2019, 01:08:08 Very tired, riding into the wind \n", "9 Oct 2019, 13:55:40 Really cold! But feeling good \n", "10 Oct 2019, 00:10:31 Feeling good after a holiday break! \n", "10 Oct 2019, 13:47:14 Stopped for photo of sunrise \n", "11 Oct 2019, 00:16:57 Bike feeling tight, needs an oil and pump \n", "\n", "[33 rows x 5 columns]" ] }, "execution_count": 43, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df = pd.read_csv('data/cycling_data.csv', index_col=0)\n", "df" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Our index is just a plain old index at the moment, with dtype `object`, full of `string` dates:" ] }, { "cell_type": "code", "execution_count": 44, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "object\n" ] }, { "data": { "text/plain": [ "pandas.core.indexes.base.Index" ] }, "execution_count": 44, "metadata": {}, "output_type": "execute_result" } ], "source": [ "print(df.index.dtype)\n", "type(df.index)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We could manually convert our index to a datetime using `pd.to_datetime()`. But even better, `pd.read_csv()` has an argument `parse_dates` which can do this automatically when reading the file:" ] }, { "cell_type": "code", "execution_count": 45, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
NameTypeTimeDistanceComments
Date
2019-09-10 00:13:04Afternoon RideRide208412.62Rain
2019-09-10 13:52:18Morning RideRide253113.03rain
2019-09-11 00:23:50Afternoon RideRide186312.52Wet road but nice weather
2019-09-11 14:06:19Morning RideRide219212.84Stopped for photo of sunrise
2019-09-12 00:28:05Afternoon RideRide189112.48Tired by the end of the week
..................
2019-10-04 01:08:08Afternoon RideRide187012.63Very tired, riding into the wind
2019-10-09 13:55:40Morning RideRide214912.70Really cold! But feeling good
2019-10-10 00:10:31Afternoon RideRide184112.59Feeling good after a holiday break!
2019-10-10 13:47:14Morning RideRide246312.79Stopped for photo of sunrise
2019-10-11 00:16:57Afternoon RideRide184311.79Bike feeling tight, needs an oil and pump
\n", "

33 rows × 5 columns

\n", "
" ], "text/plain": [ " Name Type Time Distance \\\n", "Date \n", "2019-09-10 00:13:04 Afternoon Ride Ride 2084 12.62 \n", "2019-09-10 13:52:18 Morning Ride Ride 2531 13.03 \n", "2019-09-11 00:23:50 Afternoon Ride Ride 1863 12.52 \n", "2019-09-11 14:06:19 Morning Ride Ride 2192 12.84 \n", "2019-09-12 00:28:05 Afternoon Ride Ride 1891 12.48 \n", "... ... ... ... ... \n", "2019-10-04 01:08:08 Afternoon Ride Ride 1870 12.63 \n", "2019-10-09 13:55:40 Morning Ride Ride 2149 12.70 \n", "2019-10-10 00:10:31 Afternoon Ride Ride 1841 12.59 \n", "2019-10-10 13:47:14 Morning Ride Ride 2463 12.79 \n", "2019-10-11 00:16:57 Afternoon Ride Ride 1843 11.79 \n", "\n", " Comments \n", "Date \n", "2019-09-10 00:13:04 Rain \n", "2019-09-10 13:52:18 rain \n", "2019-09-11 00:23:50 Wet road but nice weather \n", "2019-09-11 14:06:19 Stopped for photo of sunrise \n", "2019-09-12 00:28:05 Tired by the end of the week \n", "... ... \n", "2019-10-04 01:08:08 Very tired, riding into the wind \n", "2019-10-09 13:55:40 Really cold! But feeling good \n", "2019-10-10 00:10:31 Feeling good after a holiday break! \n", "2019-10-10 13:47:14 Stopped for photo of sunrise \n", "2019-10-11 00:16:57 Bike feeling tight, needs an oil and pump \n", "\n", "[33 rows x 5 columns]" ] }, "execution_count": 45, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df = pd.read_csv('data/cycling_data.csv', index_col=0, parse_dates=True)\n", "df" ] }, { "cell_type": "code", "execution_count": 46, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "pandas.core.indexes.datetimes.DatetimeIndex" ] }, "execution_count": 46, "metadata": {}, "output_type": "execute_result" } ], "source": [ "type(df.index)" ] }, { "cell_type": "code", "execution_count": 47, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "datetime64[ns]\n" ] }, { "data": { "text/plain": [ "pandas.core.indexes.datetimes.DatetimeIndex" ] }, "execution_count": 47, "metadata": {}, "output_type": "execute_result" } ], "source": [ "print(df.index.dtype)\n", "type(df.index)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The `parse_dates` argument is very flexible and you can specify the datetime format for harder to read dates. There are other related arguments like `date_parser`, `dayfirst`, etc that are also helpful, check out the [Pandas documentation](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.read_csv.html) for more." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Indexing Datetimes" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Datetime index objects are just like regular Index objects and can be selected, sliced, filtered, etc." ] }, { "cell_type": "code", "execution_count": 48, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
NameTypeTimeDistanceComments
Date
2019-09-10 00:13:04Afternoon RideRide208412.62Rain
2019-09-10 13:52:18Morning RideRide253113.03rain
2019-09-11 00:23:50Afternoon RideRide186312.52Wet road but nice weather
2019-09-11 14:06:19Morning RideRide219212.84Stopped for photo of sunrise
2019-09-12 00:28:05Afternoon RideRide189112.48Tired by the end of the week
..................
2019-10-04 01:08:08Afternoon RideRide187012.63Very tired, riding into the wind
2019-10-09 13:55:40Morning RideRide214912.70Really cold! But feeling good
2019-10-10 00:10:31Afternoon RideRide184112.59Feeling good after a holiday break!
2019-10-10 13:47:14Morning RideRide246312.79Stopped for photo of sunrise
2019-10-11 00:16:57Afternoon RideRide184311.79Bike feeling tight, needs an oil and pump
\n", "

33 rows × 5 columns

\n", "
" ], "text/plain": [ " Name Type Time Distance \\\n", "Date \n", "2019-09-10 00:13:04 Afternoon Ride Ride 2084 12.62 \n", "2019-09-10 13:52:18 Morning Ride Ride 2531 13.03 \n", "2019-09-11 00:23:50 Afternoon Ride Ride 1863 12.52 \n", "2019-09-11 14:06:19 Morning Ride Ride 2192 12.84 \n", "2019-09-12 00:28:05 Afternoon Ride Ride 1891 12.48 \n", "... ... ... ... ... \n", "2019-10-04 01:08:08 Afternoon Ride Ride 1870 12.63 \n", "2019-10-09 13:55:40 Morning Ride Ride 2149 12.70 \n", "2019-10-10 00:10:31 Afternoon Ride Ride 1841 12.59 \n", "2019-10-10 13:47:14 Morning Ride Ride 2463 12.79 \n", "2019-10-11 00:16:57 Afternoon Ride Ride 1843 11.79 \n", "\n", " Comments \n", "Date \n", "2019-09-10 00:13:04 Rain \n", "2019-09-10 13:52:18 rain \n", "2019-09-11 00:23:50 Wet road but nice weather \n", "2019-09-11 14:06:19 Stopped for photo of sunrise \n", "2019-09-12 00:28:05 Tired by the end of the week \n", "... ... \n", "2019-10-04 01:08:08 Very tired, riding into the wind \n", "2019-10-09 13:55:40 Really cold! But feeling good \n", "2019-10-10 00:10:31 Feeling good after a holiday break! \n", "2019-10-10 13:47:14 Stopped for photo of sunrise \n", "2019-10-11 00:16:57 Bike feeling tight, needs an oil and pump \n", "\n", "[33 rows x 5 columns]" ] }, "execution_count": 48, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can do partial string indexing:" ] }, { "cell_type": "code", "execution_count": 49, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
NameTypeTimeDistanceComments
Date
2019-09-10 00:13:04Afternoon RideRide208412.62Rain
2019-09-10 13:52:18Morning RideRide253113.03rain
2019-09-11 00:23:50Afternoon RideRide186312.52Wet road but nice weather
2019-09-11 14:06:19Morning RideRide219212.84Stopped for photo of sunrise
2019-09-12 00:28:05Afternoon RideRide189112.48Tired by the end of the week
..................
2019-09-25 13:35:41Morning RideRide212412.65Stopped for photo of sunrise
2019-09-26 00:13:33Afternoon RideRide186012.52raining
2019-09-26 13:42:43Morning RideRide235012.91Detour around trucks at Jericho
2019-09-27 01:00:18Afternoon RideRide171212.47Tired by the end of the week
2019-09-30 13:53:52Morning RideRide211812.71Rested after the weekend!
\n", "

22 rows × 5 columns

\n", "
" ], "text/plain": [ " Name Type Time Distance \\\n", "Date \n", "2019-09-10 00:13:04 Afternoon Ride Ride 2084 12.62 \n", "2019-09-10 13:52:18 Morning Ride Ride 2531 13.03 \n", "2019-09-11 00:23:50 Afternoon Ride Ride 1863 12.52 \n", "2019-09-11 14:06:19 Morning Ride Ride 2192 12.84 \n", "2019-09-12 00:28:05 Afternoon Ride Ride 1891 12.48 \n", "... ... ... ... ... \n", "2019-09-25 13:35:41 Morning Ride Ride 2124 12.65 \n", "2019-09-26 00:13:33 Afternoon Ride Ride 1860 12.52 \n", "2019-09-26 13:42:43 Morning Ride Ride 2350 12.91 \n", "2019-09-27 01:00:18 Afternoon Ride Ride 1712 12.47 \n", "2019-09-30 13:53:52 Morning Ride Ride 2118 12.71 \n", "\n", " Comments \n", "Date \n", "2019-09-10 00:13:04 Rain \n", "2019-09-10 13:52:18 rain \n", "2019-09-11 00:23:50 Wet road but nice weather \n", "2019-09-11 14:06:19 Stopped for photo of sunrise \n", "2019-09-12 00:28:05 Tired by the end of the week \n", "... ... \n", "2019-09-25 13:35:41 Stopped for photo of sunrise \n", "2019-09-26 00:13:33 raining \n", "2019-09-26 13:42:43 Detour around trucks at Jericho \n", "2019-09-27 01:00:18 Tired by the end of the week \n", "2019-09-30 13:53:52 Rested after the weekend! \n", "\n", "[22 rows x 5 columns]" ] }, "execution_count": 49, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.loc['2019-09']" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Exact matching:" ] }, { "cell_type": "code", "execution_count": 50, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
NameTypeTimeDistanceComments
Date
2019-10-10 00:10:31Afternoon RideRide184112.59Feeling good after a holiday break!
2019-10-10 13:47:14Morning RideRide246312.79Stopped for photo of sunrise
\n", "
" ], "text/plain": [ " Name Type Time Distance \\\n", "Date \n", "2019-10-10 00:10:31 Afternoon Ride Ride 1841 12.59 \n", "2019-10-10 13:47:14 Morning Ride Ride 2463 12.79 \n", "\n", " Comments \n", "Date \n", "2019-10-10 00:10:31 Feeling good after a holiday break! \n", "2019-10-10 13:47:14 Stopped for photo of sunrise " ] }, "execution_count": 50, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.loc['2019-10-10']" ] }, { "cell_type": "code", "execution_count": 51, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
NameTypeTimeDistanceComments
Date
2019-10-10 13:47:14Morning RideRide246312.79Stopped for photo of sunrise
\n", "
" ], "text/plain": [ " Name Type Time Distance \\\n", "Date \n", "2019-10-10 13:47:14 Morning Ride Ride 2463 12.79 \n", "\n", " Comments \n", "Date \n", "2019-10-10 13:47:14 Stopped for photo of sunrise " ] }, "execution_count": 51, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.loc['2019-10-10 13:47:14']" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And slicing:" ] }, { "cell_type": "code", "execution_count": 52, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
NameTypeTimeDistanceComments
Date
2019-10-01 00:15:07Afternoon RideRide1732NaNLegs feeling strong!
2019-10-01 13:45:55Morning RideRide222212.82Beautiful morning! Feeling fit
2019-10-02 00:13:09Afternoon RideRide1756NaNA little tired today but good weather
2019-10-02 13:46:06Morning RideRide213413.06Bit tired today but good weather
2019-10-03 00:45:22Afternoon RideRide172412.52Feeling good
2019-10-03 13:47:36Morning RideRide218212.68Wet road
2019-10-04 01:08:08Afternoon RideRide187012.63Very tired, riding into the wind
2019-10-09 13:55:40Morning RideRide214912.70Really cold! But feeling good
2019-10-10 00:10:31Afternoon RideRide184112.59Feeling good after a holiday break!
2019-10-10 13:47:14Morning RideRide246312.79Stopped for photo of sunrise
2019-10-11 00:16:57Afternoon RideRide184311.79Bike feeling tight, needs an oil and pump
\n", "
" ], "text/plain": [ " Name Type Time Distance \\\n", "Date \n", "2019-10-01 00:15:07 Afternoon Ride Ride 1732 NaN \n", "2019-10-01 13:45:55 Morning Ride Ride 2222 12.82 \n", "2019-10-02 00:13:09 Afternoon Ride Ride 1756 NaN \n", "2019-10-02 13:46:06 Morning Ride Ride 2134 13.06 \n", "2019-10-03 00:45:22 Afternoon Ride Ride 1724 12.52 \n", "2019-10-03 13:47:36 Morning Ride Ride 2182 12.68 \n", "2019-10-04 01:08:08 Afternoon Ride Ride 1870 12.63 \n", "2019-10-09 13:55:40 Morning Ride Ride 2149 12.70 \n", "2019-10-10 00:10:31 Afternoon Ride Ride 1841 12.59 \n", "2019-10-10 13:47:14 Morning Ride Ride 2463 12.79 \n", "2019-10-11 00:16:57 Afternoon Ride Ride 1843 11.79 \n", "\n", " Comments \n", "Date \n", "2019-10-01 00:15:07 Legs feeling strong! \n", "2019-10-01 13:45:55 Beautiful morning! Feeling fit \n", "2019-10-02 00:13:09 A little tired today but good weather \n", "2019-10-02 13:46:06 Bit tired today but good weather \n", "2019-10-03 00:45:22 Feeling good \n", "2019-10-03 13:47:36 Wet road \n", "2019-10-04 01:08:08 Very tired, riding into the wind \n", "2019-10-09 13:55:40 Really cold! But feeling good \n", "2019-10-10 00:10:31 Feeling good after a holiday break! \n", "2019-10-10 13:47:14 Stopped for photo of sunrise \n", "2019-10-11 00:16:57 Bike feeling tight, needs an oil and pump " ] }, "execution_count": 52, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.loc['2019-10-01':'2019-10-13']" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`df.query()` will also work here:" ] }, { "cell_type": "code", "execution_count": 53, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
NameTypeTimeDistanceComments
Date
2019-10-10 00:10:31Afternoon RideRide184112.59Feeling good after a holiday break!
2019-10-10 13:47:14Morning RideRide246312.79Stopped for photo of sunrise
\n", "
" ], "text/plain": [ " Name Type Time Distance \\\n", "Date \n", "2019-10-10 00:10:31 Afternoon Ride Ride 1841 12.59 \n", "2019-10-10 13:47:14 Morning Ride Ride 2463 12.79 \n", "\n", " Comments \n", "Date \n", "2019-10-10 00:10:31 Feeling good after a holiday break! \n", "2019-10-10 13:47:14 Stopped for photo of sunrise " ] }, "execution_count": 53, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.query(\"'2019-10-10'\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And for getting all results between two times of a day, use `df.between_time()`:" ] }, { "cell_type": "code", "execution_count": 54, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
NameTypeTimeDistanceComments
Date
2019-09-10 00:13:04Afternoon RideRide208412.62Rain
2019-09-11 00:23:50Afternoon RideRide186312.52Wet road but nice weather
2019-09-12 00:28:05Afternoon RideRide189112.48Tired by the end of the week
2019-09-17 00:15:47Afternoon RideRide197312.45Legs feeling strong!
2019-09-18 00:15:52Afternoon RideRide210112.48Pumped up tires
2019-09-19 00:30:01Afternoon RideRide4806212.48Feeling good
2019-09-24 00:35:42Afternoon RideRide207612.47Oiled chain, bike feels smooth
2019-09-25 00:07:21Afternoon RideRide177512.10Feeling really tired
2019-09-26 00:13:33Afternoon RideRide186012.52raining
2019-10-01 00:15:07Afternoon RideRide1732NaNLegs feeling strong!
2019-10-02 00:13:09Afternoon RideRide1756NaNA little tired today but good weather
2019-10-03 00:45:22Afternoon RideRide172412.52Feeling good
2019-10-10 00:10:31Afternoon RideRide184112.59Feeling good after a holiday break!
2019-10-11 00:16:57Afternoon RideRide184311.79Bike feeling tight, needs an oil and pump
\n", "
" ], "text/plain": [ " Name Type Time Distance \\\n", "Date \n", "2019-09-10 00:13:04 Afternoon Ride Ride 2084 12.62 \n", "2019-09-11 00:23:50 Afternoon Ride Ride 1863 12.52 \n", "2019-09-12 00:28:05 Afternoon Ride Ride 1891 12.48 \n", "2019-09-17 00:15:47 Afternoon Ride Ride 1973 12.45 \n", "2019-09-18 00:15:52 Afternoon Ride Ride 2101 12.48 \n", "2019-09-19 00:30:01 Afternoon Ride Ride 48062 12.48 \n", "2019-09-24 00:35:42 Afternoon Ride Ride 2076 12.47 \n", "2019-09-25 00:07:21 Afternoon Ride Ride 1775 12.10 \n", "2019-09-26 00:13:33 Afternoon Ride Ride 1860 12.52 \n", "2019-10-01 00:15:07 Afternoon Ride Ride 1732 NaN \n", "2019-10-02 00:13:09 Afternoon Ride Ride 1756 NaN \n", "2019-10-03 00:45:22 Afternoon Ride Ride 1724 12.52 \n", "2019-10-10 00:10:31 Afternoon Ride Ride 1841 12.59 \n", "2019-10-11 00:16:57 Afternoon Ride Ride 1843 11.79 \n", "\n", " Comments \n", "Date \n", "2019-09-10 00:13:04 Rain \n", "2019-09-11 00:23:50 Wet road but nice weather \n", "2019-09-12 00:28:05 Tired by the end of the week \n", "2019-09-17 00:15:47 Legs feeling strong! \n", "2019-09-18 00:15:52 Pumped up tires \n", "2019-09-19 00:30:01 Feeling good \n", "2019-09-24 00:35:42 Oiled chain, bike feels smooth \n", "2019-09-25 00:07:21 Feeling really tired \n", "2019-09-26 00:13:33 raining \n", "2019-10-01 00:15:07 Legs feeling strong! \n", "2019-10-02 00:13:09 A little tired today but good weather \n", "2019-10-03 00:45:22 Feeling good \n", "2019-10-10 00:10:31 Feeling good after a holiday break! \n", "2019-10-11 00:16:57 Bike feeling tight, needs an oil and pump " ] }, "execution_count": 54, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.between_time('00:00', '01:00')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For more complicated filtering, we may have to decompose our timeseries, as we'll shown in the next section." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Manipulating Datetimes" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Decomposition" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can easily decompose our timeseries into its constituent components. There are [many attributes](https://pandas.pydata.org/pandas-docs/stable/user_guide/timeseries.html#time-date-components) that define these constituents." ] }, { "cell_type": "code", "execution_count": 55, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Int64Index([2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019,\n", " 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019,\n", " 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019],\n", " dtype='int64', name='Date')" ] }, "execution_count": 55, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.index.year" ] }, { "cell_type": "code", "execution_count": 56, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Int64Index([ 4, 18, 50, 19, 5, 48, 47, 34, 53, 52, 1, 9, 5, 41, 42, 24, 21,\n", " 41, 33, 43, 18, 52, 7, 55, 9, 6, 22, 36, 8, 40, 31, 14, 57],\n", " dtype='int64', name='Date')" ] }, "execution_count": 56, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.index.second" ] }, { "cell_type": "code", "execution_count": 57, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Int64Index([1, 1, 2, 2, 3, 0, 1, 1, 2, 2, 3, 3, 4, 0, 1, 1, 2, 2, 3, 3, 4, 0,\n", " 1, 1, 2, 2, 3, 3, 4, 2, 3, 3, 4],\n", " dtype='int64', name='Date')" ] }, "execution_count": 57, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.index.weekday" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As well as methods we can use:" ] }, { "cell_type": "code", "execution_count": 58, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Index(['Tuesday', 'Tuesday', 'Wednesday', 'Wednesday', 'Thursday', 'Monday',\n", " 'Tuesday', 'Tuesday', 'Wednesday', 'Wednesday', 'Thursday', 'Thursday',\n", " 'Friday', 'Monday', 'Tuesday', 'Tuesday', 'Wednesday', 'Wednesday',\n", " 'Thursday', 'Thursday', 'Friday', 'Monday', 'Tuesday', 'Tuesday',\n", " 'Wednesday', 'Wednesday', 'Thursday', 'Thursday', 'Friday', 'Wednesday',\n", " 'Thursday', 'Thursday', 'Friday'],\n", " dtype='object', name='Date')" ] }, "execution_count": 58, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.index.day_name()" ] }, { "cell_type": "code", "execution_count": 59, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Index(['September', 'September', 'September', 'September', 'September',\n", " 'September', 'September', 'September', 'September', 'September',\n", " 'September', 'September', 'September', 'September', 'September',\n", " 'September', 'September', 'September', 'September', 'September',\n", " 'September', 'September', 'October', 'October', 'October', 'October',\n", " 'October', 'October', 'October', 'October', 'October', 'October',\n", " 'October'],\n", " dtype='object', name='Date')" ] }, "execution_count": 59, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.index.month_name()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note that if you're operating on a Series rather than a DatetimeIndex object, you can access this functionality through the `.dt` attribute:" ] }, { "cell_type": "code", "execution_count": 60, "metadata": { "tags": [ "raises-exception" ] }, "outputs": [ { "ename": "AttributeError", "evalue": "'Series' object has no attribute 'year'", "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[0ms\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mpd\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mSeries\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mpd\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdate_range\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'2011-12-29'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'2011-12-31'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0ms\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0myear\u001b[0m \u001b[0;31m# raises error\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;32m/opt/miniconda3/lib/python3.7/site-packages/pandas/core/generic.py\u001b[0m in \u001b[0;36m__getattr__\u001b[0;34m(self, name)\u001b[0m\n\u001b[1;32m 5128\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_info_axis\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_can_hold_identifiers_and_holds_name\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mname\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5129\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mname\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 5130\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mobject\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m__getattribute__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mname\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 5131\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5132\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m__setattr__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mname\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mstr\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mvalue\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m->\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;31mAttributeError\u001b[0m: 'Series' object has no attribute 'year'" ] } ], "source": [ "s = pd.Series(pd.date_range('2011-12-29', '2011-12-31'))\n", "s.year # raises error" ] }, { "cell_type": "code", "execution_count": 61, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0 2011\n", "1 2011\n", "2 2011\n", "dtype: int64" ] }, "execution_count": 61, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s.dt.year # works" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Offsets and Timezones" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We saw before how we can use `Timedelta` to add/subtract time to our datetimes. `Timedelta` respects absolute time, which can be problematic in some cases, where time is not regular. For example, on March 8, Canada daylight savings started and clocks **moved forward 1 hour**. This extra \"calendar hour\" is not accounted for in absolute time:" ] }, { "cell_type": "code", "execution_count": 62, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Original time: 2020-03-07 12:00:00-08:00\n", " Plus one day: 2020-03-08 13:00:00-07:00\n" ] } ], "source": [ "t1 = pd.Timestamp('2020-03-07 12:00:00', tz='Canada/Pacific')\n", "t2 = t1 + pd.Timedelta(\"1 day\")\n", "print(f\"Original time: {t1}\")\n", "print(f\" Plus one day: {t2}\") # note that time has moved from 12:00 -> 13:00" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Instead, we'd need to use a `Dateoffset`:" ] }, { "cell_type": "code", "execution_count": 63, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Original time: 2020-03-07 12:00:00-08:00\n", " Plus one day: 2020-03-08 12:00:00-07:00\n" ] } ], "source": [ "t3 = t1 + pd.DateOffset(days=1)\n", "print(f\"Original time: {t1}\")\n", "print(f\" Plus one day: {t3}\") # note that time has stayed at 12:00" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can see that we started including timezone information above. By default, datetime objects are \"timezone unaware\". To associate times with a timezone, we can use the `tz` argument in construction, or we can use the `tz_localize()` method:" ] }, { "cell_type": "code", "execution_count": 64, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " No timezone: None\n", " tz arg: Canada/Pacific\n", ".tz_localize method: Canada/Pacific\n" ] } ], "source": [ "print(f\" No timezone: {pd.Timestamp('2020-03-07 12:00:00').tz}\")\n", "print(f\" tz arg: {pd.Timestamp('2020-03-07 12:00:00', tz='Canada/Pacific').tz}\")\n", "print(f\".tz_localize method: {pd.Timestamp('2020-03-07 12:00:00').tz_localize('Canada/Pacific').tz}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can convert between timezones using the `.tz_convert()` method. You might have noticed something funny about the times I've been riding to University:" ] }, { "cell_type": "code", "execution_count": 65, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
NameTypeTimeDistanceComments
Date
2019-09-10 00:13:04Afternoon RideRide208412.62Rain
2019-09-10 13:52:18Morning RideRide253113.03rain
2019-09-11 00:23:50Afternoon RideRide186312.52Wet road but nice weather
2019-09-11 14:06:19Morning RideRide219212.84Stopped for photo of sunrise
2019-09-12 00:28:05Afternoon RideRide189112.48Tired by the end of the week
..................
2019-10-04 01:08:08Afternoon RideRide187012.63Very tired, riding into the wind
2019-10-09 13:55:40Morning RideRide214912.70Really cold! But feeling good
2019-10-10 00:10:31Afternoon RideRide184112.59Feeling good after a holiday break!
2019-10-10 13:47:14Morning RideRide246312.79Stopped for photo of sunrise
2019-10-11 00:16:57Afternoon RideRide184311.79Bike feeling tight, needs an oil and pump
\n", "

33 rows × 5 columns

\n", "
" ], "text/plain": [ " Name Type Time Distance \\\n", "Date \n", "2019-09-10 00:13:04 Afternoon Ride Ride 2084 12.62 \n", "2019-09-10 13:52:18 Morning Ride Ride 2531 13.03 \n", "2019-09-11 00:23:50 Afternoon Ride Ride 1863 12.52 \n", "2019-09-11 14:06:19 Morning Ride Ride 2192 12.84 \n", "2019-09-12 00:28:05 Afternoon Ride Ride 1891 12.48 \n", "... ... ... ... ... \n", "2019-10-04 01:08:08 Afternoon Ride Ride 1870 12.63 \n", "2019-10-09 13:55:40 Morning Ride Ride 2149 12.70 \n", "2019-10-10 00:10:31 Afternoon Ride Ride 1841 12.59 \n", "2019-10-10 13:47:14 Morning Ride Ride 2463 12.79 \n", "2019-10-11 00:16:57 Afternoon Ride Ride 1843 11.79 \n", "\n", " Comments \n", "Date \n", "2019-09-10 00:13:04 Rain \n", "2019-09-10 13:52:18 rain \n", "2019-09-11 00:23:50 Wet road but nice weather \n", "2019-09-11 14:06:19 Stopped for photo of sunrise \n", "2019-09-12 00:28:05 Tired by the end of the week \n", "... ... \n", "2019-10-04 01:08:08 Very tired, riding into the wind \n", "2019-10-09 13:55:40 Really cold! But feeling good \n", "2019-10-10 00:10:31 Feeling good after a holiday break! \n", "2019-10-10 13:47:14 Stopped for photo of sunrise \n", "2019-10-11 00:16:57 Bike feeling tight, needs an oil and pump \n", "\n", "[33 rows x 5 columns]" ] }, "execution_count": 65, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df = pd.read_csv('data/cycling_data.csv', index_col=0, parse_dates=True)\n", "df" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "I know for a fact that I haven't been cycling around midnight... There's something wrong with the timezone in this dataset. I was using the `Strava` app to document my rides, it was recording in Canadian time but converting to Australia time. Let's go ahead and fix that up:" ] }, { "cell_type": "code", "execution_count": 66, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
NameTypeTimeDistanceComments
Date
2019-09-10 17:13:04+10:00Afternoon RideRide208412.62Rain
2019-09-11 06:52:18+10:00Morning RideRide253113.03rain
2019-09-11 17:23:50+10:00Afternoon RideRide186312.52Wet road but nice weather
2019-09-12 07:06:19+10:00Morning RideRide219212.84Stopped for photo of sunrise
2019-09-12 17:28:05+10:00Afternoon RideRide189112.48Tired by the end of the week
..................
2019-10-04 18:08:08+10:00Afternoon RideRide187012.63Very tired, riding into the wind
2019-10-10 07:55:40+11:00Morning RideRide214912.70Really cold! But feeling good
2019-10-10 18:10:31+11:00Afternoon RideRide184112.59Feeling good after a holiday break!
2019-10-11 07:47:14+11:00Morning RideRide246312.79Stopped for photo of sunrise
2019-10-11 18:16:57+11:00Afternoon RideRide184311.79Bike feeling tight, needs an oil and pump
\n", "

33 rows × 5 columns

\n", "
" ], "text/plain": [ " Name Type Time Distance \\\n", "Date \n", "2019-09-10 17:13:04+10:00 Afternoon Ride Ride 2084 12.62 \n", "2019-09-11 06:52:18+10:00 Morning Ride Ride 2531 13.03 \n", "2019-09-11 17:23:50+10:00 Afternoon Ride Ride 1863 12.52 \n", "2019-09-12 07:06:19+10:00 Morning Ride Ride 2192 12.84 \n", "2019-09-12 17:28:05+10:00 Afternoon Ride Ride 1891 12.48 \n", "... ... ... ... ... \n", "2019-10-04 18:08:08+10:00 Afternoon Ride Ride 1870 12.63 \n", "2019-10-10 07:55:40+11:00 Morning Ride Ride 2149 12.70 \n", "2019-10-10 18:10:31+11:00 Afternoon Ride Ride 1841 12.59 \n", "2019-10-11 07:47:14+11:00 Morning Ride Ride 2463 12.79 \n", "2019-10-11 18:16:57+11:00 Afternoon Ride Ride 1843 11.79 \n", "\n", " Comments \n", "Date \n", "2019-09-10 17:13:04+10:00 Rain \n", "2019-09-11 06:52:18+10:00 rain \n", "2019-09-11 17:23:50+10:00 Wet road but nice weather \n", "2019-09-12 07:06:19+10:00 Stopped for photo of sunrise \n", "2019-09-12 17:28:05+10:00 Tired by the end of the week \n", "... ... \n", "2019-10-04 18:08:08+10:00 Very tired, riding into the wind \n", "2019-10-10 07:55:40+11:00 Really cold! But feeling good \n", "2019-10-10 18:10:31+11:00 Feeling good after a holiday break! \n", "2019-10-11 07:47:14+11:00 Stopped for photo of sunrise \n", "2019-10-11 18:16:57+11:00 Bike feeling tight, needs an oil and pump \n", "\n", "[33 rows x 5 columns]" ] }, "execution_count": 66, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.index = df.index.tz_localize(\"Canada/Pacific\") # first specify the current timezone\n", "df.index = df.index.tz_convert(\"Australia/Sydney\") # then convert to the proper timezone\n", "df" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We could have also used a `DateOffset` if we knew the offset we wanted to apply, in this case, 7 hours:" ] }, { "cell_type": "code", "execution_count": 67, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
NameTypeTimeDistanceComments
Date
2019-09-09 17:13:04Afternoon RideRide208412.62Rain
2019-09-10 06:52:18Morning RideRide253113.03rain
2019-09-10 17:23:50Afternoon RideRide186312.52Wet road but nice weather
2019-09-11 07:06:19Morning RideRide219212.84Stopped for photo of sunrise
2019-09-11 17:28:05Afternoon RideRide189112.48Tired by the end of the week
..................
2019-10-03 18:08:08Afternoon RideRide187012.63Very tired, riding into the wind
2019-10-09 06:55:40Morning RideRide214912.70Really cold! But feeling good
2019-10-09 17:10:31Afternoon RideRide184112.59Feeling good after a holiday break!
2019-10-10 06:47:14Morning RideRide246312.79Stopped for photo of sunrise
2019-10-10 17:16:57Afternoon RideRide184311.79Bike feeling tight, needs an oil and pump
\n", "

33 rows × 5 columns

\n", "
" ], "text/plain": [ " Name Type Time Distance \\\n", "Date \n", "2019-09-09 17:13:04 Afternoon Ride Ride 2084 12.62 \n", "2019-09-10 06:52:18 Morning Ride Ride 2531 13.03 \n", "2019-09-10 17:23:50 Afternoon Ride Ride 1863 12.52 \n", "2019-09-11 07:06:19 Morning Ride Ride 2192 12.84 \n", "2019-09-11 17:28:05 Afternoon Ride Ride 1891 12.48 \n", "... ... ... ... ... \n", "2019-10-03 18:08:08 Afternoon Ride Ride 1870 12.63 \n", "2019-10-09 06:55:40 Morning Ride Ride 2149 12.70 \n", "2019-10-09 17:10:31 Afternoon Ride Ride 1841 12.59 \n", "2019-10-10 06:47:14 Morning Ride Ride 2463 12.79 \n", "2019-10-10 17:16:57 Afternoon Ride Ride 1843 11.79 \n", "\n", " Comments \n", "Date \n", "2019-09-09 17:13:04 Rain \n", "2019-09-10 06:52:18 rain \n", "2019-09-10 17:23:50 Wet road but nice weather \n", "2019-09-11 07:06:19 Stopped for photo of sunrise \n", "2019-09-11 17:28:05 Tired by the end of the week \n", "... ... \n", "2019-10-03 18:08:08 Very tired, riding into the wind \n", "2019-10-09 06:55:40 Really cold! But feeling good \n", "2019-10-09 17:10:31 Feeling good after a holiday break! \n", "2019-10-10 06:47:14 Stopped for photo of sunrise \n", "2019-10-10 17:16:57 Bike feeling tight, needs an oil and pump \n", "\n", "[33 rows x 5 columns]" ] }, "execution_count": 67, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df = pd.read_csv('data/cycling_data.csv', index_col=0, parse_dates=True)\n", "df.index = df.index + pd.DateOffset(hours=-7)\n", "df" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Resampling and Aggregating" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "One of the most common operations you will want do when working with time series is resampling the time series to a coarser/finer/regular resolution. For example, you may want to resample daily data to weekly data. We can do that with the `.resample()` method. For example, let's resample my irregular cycling timeseries to a regular 12-hourly series:" ] }, { "cell_type": "code", "execution_count": 68, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "DatetimeIndex(['2019-09-09 17:13:04', '2019-09-10 06:52:18',\n", " '2019-09-10 17:23:50', '2019-09-11 07:06:19',\n", " '2019-09-11 17:28:05', '2019-09-16 06:57:48',\n", " '2019-09-16 17:15:47', '2019-09-17 06:43:34',\n", " '2019-09-18 06:49:53', '2019-09-17 17:15:52',\n", " '2019-09-18 17:30:01', '2019-09-19 06:52:09',\n", " '2019-09-19 18:02:05', '2019-09-23 06:50:41',\n", " '2019-09-23 17:35:42', '2019-09-24 06:41:24',\n", " '2019-09-24 17:07:21', '2019-09-25 06:35:41',\n", " '2019-09-25 17:13:33', '2019-09-26 06:42:43',\n", " '2019-09-26 18:00:18', '2019-09-30 06:53:52',\n", " '2019-09-30 17:15:07', '2019-10-01 06:45:55',\n", " '2019-10-01 17:13:09', '2019-10-02 06:46:06',\n", " '2019-10-02 17:45:22', '2019-10-03 06:47:36',\n", " '2019-10-03 18:08:08', '2019-10-09 06:55:40',\n", " '2019-10-09 17:10:31', '2019-10-10 06:47:14',\n", " '2019-10-10 17:16:57'],\n", " dtype='datetime64[ns]', name='Date', freq=None)" ] }, "execution_count": 68, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.index" ] }, { "cell_type": "code", "execution_count": 69, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 69, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.resample(\"1D\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`Resampler` objects are very similar to the `groupby` objects we saw in the previous chapter. We need to apply an aggregating function on our grouped timeseries, just like we did with `groupby` objects:" ] }, { "cell_type": "code", "execution_count": 70, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
TimeDistance
Date
2019-09-092084.012.620
2019-09-102197.012.775
2019-09-112041.512.660
2019-09-12NaNNaN
2019-09-13NaNNaN
.........
2019-10-06NaNNaN
2019-10-07NaNNaN
2019-10-08NaNNaN
2019-10-091995.012.645
2019-10-102153.012.290
\n", "

32 rows × 2 columns

\n", "
" ], "text/plain": [ " Time Distance\n", "Date \n", "2019-09-09 2084.0 12.620\n", "2019-09-10 2197.0 12.775\n", "2019-09-11 2041.5 12.660\n", "2019-09-12 NaN NaN\n", "2019-09-13 NaN NaN\n", "... ... ...\n", "2019-10-06 NaN NaN\n", "2019-10-07 NaN NaN\n", "2019-10-08 NaN NaN\n", "2019-10-09 1995.0 12.645\n", "2019-10-10 2153.0 12.290\n", "\n", "[32 rows x 2 columns]" ] }, "execution_count": 70, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dfr = df.resample(\"1D\").mean()\n", "dfr" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "There's quite a few `NaN`s in there? Some days I didn't ride, but some might by weekends too..." ] }, { "cell_type": "code", "execution_count": 71, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
TimeDistanceWeekday
Date
2019-09-092084.012.620Monday
2019-09-102197.012.775Tuesday
2019-09-112041.512.660Wednesday
2019-09-12NaNNaNThursday
2019-09-13NaNNaNFriday
2019-09-14NaNNaNSaturday
2019-09-15NaNNaNSunday
2019-09-162122.512.450Monday
2019-09-172193.012.540Tuesday
2019-09-1825482.513.525Wednesday
\n", "
" ], "text/plain": [ " Time Distance Weekday\n", "Date \n", "2019-09-09 2084.0 12.620 Monday\n", "2019-09-10 2197.0 12.775 Tuesday\n", "2019-09-11 2041.5 12.660 Wednesday\n", "2019-09-12 NaN NaN Thursday\n", "2019-09-13 NaN NaN Friday\n", "2019-09-14 NaN NaN Saturday\n", "2019-09-15 NaN NaN Sunday\n", "2019-09-16 2122.5 12.450 Monday\n", "2019-09-17 2193.0 12.540 Tuesday\n", "2019-09-18 25482.5 13.525 Wednesday" ] }, "execution_count": 71, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dfr['Weekday'] = dfr.index.day_name()\n", "dfr.head(10)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Pandas support \"business time\" operations and format codes in all the timeseries functions we've seen so far. You can check out [the documentation](https://pandas.pydata.org/pandas-docs/stable/user_guide/timeseries.html) for more info, but let's specify business days here to get rid of those weekends:" ] }, { "cell_type": "code", "execution_count": 72, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
TimeDistanceWeekday
Date
2019-09-092084.012.620Monday
2019-09-102197.012.775Tuesday
2019-09-112041.512.660Wednesday
2019-09-12NaNNaNThursday
2019-09-13NaNNaNFriday
2019-09-162122.512.450Monday
2019-09-172193.012.540Tuesday
2019-09-1825482.513.525Wednesday
2019-09-192525.512.700Thursday
2019-09-20NaNNaNFriday
\n", "
" ], "text/plain": [ " Time Distance Weekday\n", "Date \n", "2019-09-09 2084.0 12.620 Monday\n", "2019-09-10 2197.0 12.775 Tuesday\n", "2019-09-11 2041.5 12.660 Wednesday\n", "2019-09-12 NaN NaN Thursday\n", "2019-09-13 NaN NaN Friday\n", "2019-09-16 2122.5 12.450 Monday\n", "2019-09-17 2193.0 12.540 Tuesday\n", "2019-09-18 25482.5 13.525 Wednesday\n", "2019-09-19 2525.5 12.700 Thursday\n", "2019-09-20 NaN NaN Friday" ] }, "execution_count": 72, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dfr = df.resample(\"1B\").mean() # \"B\" is business day\n", "dfr['Weekday'] = dfr.index.day_name()\n", "dfr.head(10)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 3. Hierachical Indexing\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Hierachical indexing**, sometimes called \"multi-indexing\" or \"stacked indexing\", is how Pandas \"nests\" data. The idea is to facilitate the storage of high dimensional data in a 2D dataframe." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![](img/chapter9/pandas_stacking.gif)\n", "\n", "Source: [Giphy](https://giphy.com/gifs/panda-playing-QoCoLo2opwUW4)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Creating a Hierachical Index" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's start with a motivating example. Say you want to track how many courses each Master of Data Science instructor taught over the years in a Pandas Series.\n", "\n", "```{note}\n", "Recall that the content of this site is adapted from material I used to teach the 2020/2021 offering of the course \"DSCI 511 Python Programming for Data Science\" for the University of British Columbia's Master of Data Science Program.\n", "```\n", "\n", "We could use a tuple to make an appropriate index:" ] }, { "cell_type": "code", "execution_count": 73, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(Tom, 2019) 4\n", "(Tom, 2020) 6\n", "(Mike, 2019) 5\n", "(Mike, 2020) 5\n", "(Tiffany, 2019) 6\n", "(Tiffany, 2020) 3\n", "dtype: int64" ] }, "execution_count": 73, "metadata": {}, "output_type": "execute_result" } ], "source": [ "index = [('Tom', 2019), ('Tom', 2020),\n", " ('Mike', 2019), ('Mike', 2020),\n", " ('Tiffany', 2019), ('Tiffany', 2020)]\n", "courses = [4, 6, 5, 5, 6, 3]\n", "s = pd.Series(courses, index)\n", "s" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can still kind of index this series:" ] }, { "cell_type": "code", "execution_count": 74, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(Tom, 2019) 4\n", "dtype: int64" ] }, "execution_count": 74, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s.loc[(\"Tom\", 2019):(\"Tom\", 2019)]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "But if we wanted to get all of the values for 2019, we'd need to do some messy looping:" ] }, { "cell_type": "code", "execution_count": 75, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(Tom, 2019) 4\n", "(Mike, 2019) 5\n", "(Tiffany, 2019) 6\n", "dtype: int64" ] }, "execution_count": 75, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s[[i for i in s.index if i[1] == 2019]]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The better way to set up this problem is with a multi-index (\"hierachical index\"). We can create a multi-index with `pd.MultiIndex.from_tuple()`. There are [other variations](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.MultiIndex.html) of `.from_X` but tuple is most common." ] }, { "cell_type": "code", "execution_count": 76, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "MultiIndex([( 'Tom', 2019),\n", " ( 'Tom', 2020),\n", " ( 'Mike', 2019),\n", " ( 'Mike', 2020),\n", " ('Tiffany', 2019),\n", " ('Tiffany', 2020)],\n", " )" ] }, "execution_count": 76, "metadata": {}, "output_type": "execute_result" } ], "source": [ "mi = pd.MultiIndex.from_tuples(index)\n", "mi" ] }, { "cell_type": "code", "execution_count": 77, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Tom 2019 4\n", " 2020 6\n", "Mike 2019 5\n", " 2020 5\n", "Tiffany 2019 6\n", " 2020 3\n", "dtype: int64" ] }, "execution_count": 77, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s = pd.Series(courses, mi)\n", "s" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now we can do more efficient and logical indexing:" ] }, { "cell_type": "code", "execution_count": 78, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "2019 4\n", "2020 6\n", "dtype: int64" ] }, "execution_count": 78, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s.loc['Tom']" ] }, { "cell_type": "code", "execution_count": 79, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Tom 4\n", "Mike 5\n", "Tiffany 6\n", "dtype: int64" ] }, "execution_count": 79, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s.loc[:, 2019]" ] }, { "cell_type": "code", "execution_count": 80, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "4" ] }, "execution_count": 80, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s.loc[\"Tom\", 2019]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We could also create the index by passing iterables like a list of lists directly to the `index` argument, but I feel it's not as explicit or intutitive as using `pd.MultIndex`:" ] }, { "cell_type": "code", "execution_count": 81, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Tom 2019 4\n", " 2020 6\n", "Mike 2019 5\n", " 2020 5\n", "Tiffany 2019 6\n", " 2020 3\n", "dtype: int64" ] }, "execution_count": 81, "metadata": {}, "output_type": "execute_result" } ], "source": [ "index = [['Tom', 'Tom', 'Mike', 'Mike', 'Tiffany', 'Tiffany'],\n", " [2019, 2020, 2019, 2020, 2019, 2020]]\n", "courses = [4, 6, 5, 5, 6, 3]\n", "s = pd.Series(courses, index)\n", "s" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Stacking / Unstacking" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You might have noticed that we could also represent our multi-index series as a dataframe. Pandas noticed this too and provides the `.stack()` and `.unstack()` methods for switching between dataframes and multi-index series:" ] }, { "cell_type": "code", "execution_count": 82, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
20192020
Mike55
Tiffany63
Tom46
\n", "
" ], "text/plain": [ " 2019 2020\n", "Mike 5 5\n", "Tiffany 6 3\n", "Tom 4 6" ] }, "execution_count": 82, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s = s.unstack()\n", "s" ] }, { "cell_type": "code", "execution_count": 83, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Mike 2019 5\n", " 2020 5\n", "Tiffany 2019 6\n", " 2020 3\n", "Tom 2019 4\n", " 2020 6\n", "dtype: int64" ] }, "execution_count": 83, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s.stack()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Using a Hierachical Index" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Observing the multi-index <-> dataframe equivalence above, you might wonder why we would even want multi-indices. Above, we were only dealing with 2D data, but a multi-index allows us to store any arbitrary number of dimensions:" ] }, { "cell_type": "code", "execution_count": 84, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Tom 2019 4\n", " 2020 6\n", "Mike 2019 5\n", " 2020 5\n", "Tiffany 2019 6\n", " 2020 3\n", "dtype: int64" ] }, "execution_count": 84, "metadata": {}, "output_type": "execute_result" } ], "source": [ "index = [['Tom', 'Tom', 'Mike', 'Mike', 'Tiffany', 'Tiffany'],\n", " [2019, 2020, 2019, 2020, 2019, 2020]]\n", "courses = [4, 6, 5, 5, 6, 3]\n", "s = pd.Series(courses, index)\n", "s" ] }, { "cell_type": "code", "execution_count": 85, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Tom 2019 0 4\n", " 2020 0 6\n", "Mike 2019 0 5\n", " 2020 0 5\n", "Tiffany 2019 0 6\n", " 2020 0 3\n", "dtype: int64" ] }, "execution_count": 85, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pd.DataFrame(s).stack()" ] }, { "cell_type": "code", "execution_count": 86, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "2019 4\n", "2020 6\n", "dtype: int64" ] }, "execution_count": 86, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s.loc['Tom']" ] }, { "cell_type": "code", "execution_count": 87, "metadata": {}, "outputs": [], "source": [ "tom = pd.DataFrame({\"Courses\": [4, 6],\n", " \"Students\": [273, 342]},\n", " index = [2019, 2020])\n", "mike = pd.DataFrame({\"Courses\": [5, 5],\n", " \"Students\": [293, 420]},\n", " index = [2019, 2020])\n", "tiff = pd.DataFrame({\"Courses\": [6, 3],\n", " \"Students\": [363, 190]},\n", " index = [2019, 2020])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here I have three 2D dataframes that I'd like to join together. There are so many ways you can do this, but I'm going to use `pd.concat()` and then specify the `keys` argument:" ] }, { "cell_type": "code", "execution_count": 88, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
CoursesStudents
Tom20194273
20206342
Mike20195293
20205420
Tiff20196363
20203190
\n", "
" ], "text/plain": [ " Courses Students\n", "Tom 2019 4 273\n", " 2020 6 342\n", "Mike 2019 5 293\n", " 2020 5 420\n", "Tiff 2019 6 363\n", " 2020 3 190" ] }, "execution_count": 88, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s3 = pd.concat((tom, mike, tiff),\n", " keys= ['Tom', 'Mike', 'Tiff'],\n", " axis=0)\n", "s3" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now we have 3 dimensions of information in a single structure!" ] }, { "cell_type": "code", "execution_count": 89, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Tom 2019 Courses 4\n", " Students 273\n", " 2020 Courses 6\n", " Students 342\n", "Mike 2019 Courses 5\n", " Students 293\n", " 2020 Courses 5\n", " Students 420\n", "Tiff 2019 Courses 6\n", " Students 363\n", " 2020 Courses 3\n", " Students 190\n", "dtype: int64" ] }, "execution_count": 89, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s3.stack()" ] }, { "cell_type": "code", "execution_count": 90, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
CoursesStudents
20194273
20206342
\n", "
" ], "text/plain": [ " Courses Students\n", "2019 4 273\n", "2020 6 342" ] }, "execution_count": 90, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s3.loc['Tom']" ] }, { "cell_type": "code", "execution_count": 91, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Courses 4\n", "Students 273\n", "Name: (Tom, 2019), dtype: int64" ] }, "execution_count": 91, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s3.loc['Tom', 2019]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can access deeper levels in various ways:" ] }, { "cell_type": "code", "execution_count": 92, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "4" ] }, "execution_count": 92, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s3.loc['Tom', 2019]['Courses']" ] }, { "cell_type": "code", "execution_count": 93, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "4" ] }, "execution_count": 93, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s3.loc[('Tom', 2019), 'Courses']" ] }, { "cell_type": "code", "execution_count": 94, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "4" ] }, "execution_count": 94, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s3.loc[('Tom', 2019), 'Courses']" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If we name our index columns, we can also use `.query()`:" ] }, { "cell_type": "code", "execution_count": 95, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
CoursesStudents
NameYear
Tom20194273
20206342
Mike20195293
20205420
Tiff20196363
20203190
\n", "
" ], "text/plain": [ " Courses Students\n", "Name Year \n", "Tom 2019 4 273\n", " 2020 6 342\n", "Mike 2019 5 293\n", " 2020 5 420\n", "Tiff 2019 6 363\n", " 2020 3 190" ] }, "execution_count": 95, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s3 = s3.rename_axis(index=[\"Name\", \"Year\"])\n", "s3" ] }, { "cell_type": "code", "execution_count": 96, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
CoursesStudents
NameYear
Tom20194273
Mike20195293
Tiff20196363
\n", "
" ], "text/plain": [ " Courses Students\n", "Name Year \n", "Tom 2019 4 273\n", "Mike 2019 5 293\n", "Tiff 2019 6 363" ] }, "execution_count": 96, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s3.query(\"Year == 2019\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Or you might prefer the \"stacked\" version of our hierachical index:" ] }, { "cell_type": "code", "execution_count": 97, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Name Year \n", "Tom 2019 Courses 4\n", " Students 273\n", " 2020 Courses 6\n", " Students 342\n", "Mike 2019 Courses 5\n", " Students 293\n", " 2020 Courses 5\n", " Students 420\n", "Tiff 2019 Courses 6\n", " Students 363\n", " 2020 Courses 3\n", " Students 190\n", "dtype: int64" ] }, "execution_count": 97, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s3.stack()" ] }, { "cell_type": "code", "execution_count": 98, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "4" ] }, "execution_count": 98, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s3.stack().loc[('Tom', 2019, 'Courses')]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "By the way, we can also use all the previous methods we've learned about on hierachical dataframes:" ] }, { "cell_type": "code", "execution_count": 99, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
CoursesStudents
NameYear
Tom20206342
20194273
Tiff20203190
20196363
Mike20205420
20195293
\n", "
" ], "text/plain": [ " Courses Students\n", "Name Year \n", "Tom 2020 6 342\n", " 2019 4 273\n", "Tiff 2020 3 190\n", " 2019 6 363\n", "Mike 2020 5 420\n", " 2019 5 293" ] }, "execution_count": 99, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s3.sort_index(ascending=False)" ] }, { "cell_type": "code", "execution_count": 100, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
CoursesStudents
NameYear
Tiff20203190
Tom20194273
Mike20195293
Tom20206342
Tiff20196363
Mike20205420
\n", "
" ], "text/plain": [ " Courses Students\n", "Name Year \n", "Tiff 2020 3 190\n", "Tom 2019 4 273\n", "Mike 2019 5 293\n", "Tom 2020 6 342\n", "Tiff 2019 6 363\n", "Mike 2020 5 420" ] }, "execution_count": 100, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s3.sort_values(by='Students')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "There's one important exception! We can now specify a `level` argument to chose which level of our multi-index to apply the function to:" ] }, { "cell_type": "code", "execution_count": 101, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Courses 4.833333\n", "Students 313.500000\n", "dtype: float64" ] }, "execution_count": 101, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s3.mean()" ] }, { "cell_type": "code", "execution_count": 102, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
CoursesStudents
Year
20195.000000309.666667
20204.666667317.333333
\n", "
" ], "text/plain": [ " Courses Students\n", "Year \n", "2019 5.000000 309.666667\n", "2020 4.666667 317.333333" ] }, "execution_count": 102, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s3.mean(level='Year')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 4. Visualizing DataFrames\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Pandas provides a `.plot()` method on Series and DataFrames which I wanted to show briefly here." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Simple Plots" ] }, { "cell_type": "code", "execution_count": 103, "metadata": {}, "outputs": [], "source": [ "df = pd.read_csv('data/cycling_data.csv', index_col=0, parse_dates=True).dropna()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's go ahead and make a plot of the distances I've ridden:" ] }, { "cell_type": "code", "execution_count": 104, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "df['Distance'].plot.line();" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Cumulative distance might be more informative:" ] }, { "cell_type": "code", "execution_count": 105, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "df['Distance'].cumsum().plot.line();" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "There are many configuration options for these plots which build of the `matplotlib` library:" ] }, { "cell_type": "code", "execution_count": 106, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "df['Distance'].cumsum().plot.line(fontsize=14, linewidth = 2, color = 'r', ylabel=\"km\");" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "I actually usually use built-in themes for my plots which do a lot of the colour and text formatting for you:" ] }, { "cell_type": "code", "execution_count": 107, "metadata": {}, "outputs": [], "source": [ "import matplotlib.pyplot as plt\n", "plt.style.use('ggplot')\n", "plt.rcParams.update({'font.size': 16,\n", " 'axes.labelweight': 'bold',\n", " 'figure.figsize': (8,6)})" ] }, { "cell_type": "code", "execution_count": 108, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAh0AAAGNCAYAAAC17sM5AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/d3fzzAAAACXBIWXMAAAsTAAALEwEAmpwYAABgn0lEQVR4nO3de1xUdf7H8deZ4SYgigwjIiCioiLeSQ2t1Kitti111Sw1s3tq7ZZtmt3W3Syzrd2y9udmZdpVy1uWpWJ5TVMsLTU1UVREQDQvXAdmvr8/aEYRUFSYM3P4PB+PHsSZMzOf93Cc+cz3fM85mlJKIYQQQghRx0x6FyCEEEKI+kGaDiGEEEK4hTQdQgghhHALaTqEEEII4RbSdAghhBDCLaTpEEIIIYRbSNMhhBBCCLfw0buA+iArK6vK5RaLhby8PDdXU3eMlgeMl0nyeD53ZTLaa2e0POC9mSIjI6u9zfBNx5QpU9i2bRuDBg1i2LBhruX5+fl88MEHbN68GZvNRnx8PKNGjSImJqbC/W02G3PnzmXt2rUUFBQQGxvL8OHDSUhIcHcUIYQQwqsZevfKunXrOHDgQKXlSimmTZvG1q1bGT16NOPHj6esrIzJkydz7NixCuvOmDGDlStXMnToUCZOnEhoaChTpkwhIyPDTSmEEEIIYzBs01FQUMDs2bO58847K92WlpbGrl27GDduHH369KFLly5MmDABh8PB4sWLXetlZGSwbt06Ro0aRUpKCh07duTRRx/FYrEwd+5cd8YRQgghvJ5hm44PPviA6Oho+vTpU+m2tLQ0QkNDSUxMdC0LDAyke/fupKWlVVjPbDaTnJzsWmY2m+nduzfbtm2jtLS0bkMIIYQQBmLIpmPXrl2sWbOGe++9t8rbMzMzK83dAIiOjiYvL4/i4mLXelarFX9//wrrRUVFUVZWRnZ2du0XL4QQQhiU4ZqOsrIy3nrrLf70pz9VO4M2Pz+foKCgSsuDg4Ndtzt/Opedbz0hhBBCXJjhjl5ZvHgxNpuNQYMGVbuOUqpGy6tb70JSU1NJTU0FYOrUqVgslirX8/HxqfY2b2S0PGC8TJLH87krk9FeO6PlAYNm0ruA2pSXl8eCBQt48MEHKS0trTDnorS0lIKCAho0aEBwcDAFBQWV7u9c5hzJCA4OrvIYaecIR1WjIAApKSmkpKRUqKsq3noMdnWMlgeMl0nyeD45T8elMVoe8N5M9eY8HTk5OZSWljJ9+vRKty1ZsoQlS5Ywbdo0oqKi+Omnnyqtk5mZicViISAgACif47Fp0yZKSkoqzOvIzMzEx8eHiIiIugsjhBBCGIyhmo7Y2Fiee+65SssnT57MVVddRf/+/YmIiCApKYlVq1axc+dO10m+CgsL2bJlS4WjXZKSkpg3bx4bNmygb9++ANjtdjZs2ECnTp3w9fV1Sy4hhBDCCAzVdAQFBdGhQ4cqbwsPD3fdlpSURHx8PNOnT2fEiBEEBQWxaNEilFLccsstrvvExsaSnJzM7NmzsdvtWK1Wli9fTm5uLg8//LBbMgkhhBB1xTHvHbT4RLQuPd3yfIZqOmrKZDIxceJE5syZw9tvv01paSnx8fE899xzlSbtjBkzho8//phPPvmEwsJCWrRowaRJk4iLi9OpeiGEEOLyqR++Q61YDP4B0nTUpnnz5lVaFhwczJgxYy54Xz8/P0aNGsWoUaPqojQhhBDC7dTJ33C8/ya0aI32x9vc9ryGO0+HEEIIIaqnlMIxezqUlGC651E0H/eNP0jTIYQQQtQjau1y+DkNbdCdaM2i3frc0nQIIYQQ9YTKPYKa9w6074zW/2a3P780HUIIIUQ9oBx2HLP+AyYzprseQTO5vwWQpkMIIYSoB9SyRbD3F7Q77kdrEq5LDdJ0CCGEEAanDu1HLf4Quiej9eyrWx3SdAghhBAGpgryccx4CYIbYho+Bk3TdKtFmg4hhBDCoJTdjuN/L8GxXEwPTkBrGKJrPdJ0CCGEEAal5r0Dv2xDGzkWrXWC3uVI0yGEEEIYkWPN16hvvkC77lZMva/VuxxAmg4hhBDCcNTu7aiP/geJ3dAG36V3OS7SdAghhBAGoo5m45jxIoQ3w3Tf39BMZr1LcpGmQwghhDAIVVyI480p4FCYxj2NFhikd0kVSNMhhBBCGIBy2HG8/SocOVR+pErTSL1LqkSaDiGEEMIA1KIPYNsmtGH3obXvrHc5VZKmQwghhPBy6pdtqK/mo119A1rfm/Qup1rSdAghhBBeTNlKcHzwX7A2Q7vtHl3POHoh0nQIIYQQXkx9+SnkHsE0Ygyan7/e5ZyXNB1CCCGEl1KHD6CWzUe7sr/HzuM4mzQdQgghhBdSDgeO99+EBoFoQ+7Wu5wakaZDCCGE8EJqzdeQvgtt6L26X8itpqTpEEIIIbyM+u0YasEcaN8ZrVdfvcupMWk6hBBCCC/j+OQtKCsrnzzqwUernMtH7wJq29atW1m8eDGZmZkUFBQQEhJCfHw8Q4cOJSoqCoDc3FzGjRtX5f1nzZpFUNCZ08babDbmzp3L2rVrKSgoIDY2luHDh5OQoP8lgoUQQtQPqrgIjh2F47mofXvghw1og+5EszbTu7SLYrimIz8/n7i4OP7whz8QEhJCXl4eixYt4qmnnuJf//oX4eHhrnUHDBhAUlJShfs3aNCgwu8zZszghx9+YMSIETRt2pRly5YxZcoUpkyZQmxsrDsiCSGEMDhVWADHcuFYLur3nydOn8R+JBOO5UD+6Yp3aNUO7boButR6OQzXdPTp04c+ffpUWNa6dWv++te/snHjRv70pz+5ljdt2pT4+PhqHysjI4N169bx0EMP0a9fPwASEhJ47LHHmDt3LhMmTKibEEIIIQxDKQUFp8tHKo7loI4dPdNc5OXC8VwoLKh4Jz8/ysKbQWgYWovWYLFCmBUtrPwnIY3RTN43Q8JwTUdVgoODATCbL+7yvmlpaZjNZpKTk13LzGYzvXv3ZtGiRZSWluLr61urtQohhPAuSik4fQKOHUU5m4i8MyMWHDsKJUUV7+Tf4Ewj0aY9hDVFCwuHsKYQFg4NG2EJDycvL0+XTHXFsE2Hw+HA4XBw9OhRPvzwQxo3bkzv3r0rrPPRRx8xc+ZM/P39SUhI4PbbbycmJsZ1e2ZmJlarFX//imd4i4qKoqysjOzsbKKjo92SRwghhD6UwwGnfqvUSKhjOa55FthsFe8UGFQ+ImFtVn7SrrNHKSxWCAz2qgmgtcWwTcekSZPYt28fABERETz77LM0atQIAF9fX1JSUujcuTMhISEcPnyYhQsX8vTTT/PCCy+4Jpzm5+e7RknO5lyWn59f5XOnpqaSmpoKwNSpU7FYLFWu5+PjU+1t3shoecB4mSSP53NXJqO9dpeTR9ntOI4fxX40G3vuEey52diPZuPIPVL+82gOlJVWuI8W0hif8AjMLVtj7tEHs7UZZmszTOERmMMjMAVV/uxwZyZPZdimY9y4cRQVFZGTk8OSJUt4/vnn+cc//oHVaiU0NJT777/ftW779u3p0qUL48ePZ8GCBTzyyCPA70NmlyAlJYWUlBTX79UNj1ksFkMNnRktDxgvk+TxfO7KZLTX7nx5VFkZ/JZXYZImebmo40chLwdOHAO7veKdGoVCk3C0qJZonXqA5ayRiibhaAENUEDZ7/9VUFRc/l8dZvJkkZGR1d5m2KbDOVrRpk0bunbtytixY1m0aFGFZuNsFouFdu3akZ6e7loWHBxc5R/cOcJR1SiIEEII91KlpZRlHULt3VU+SfP3eRUq7/cG48RxUI4zd9A0aNSkvJFo1f73uRXhaM75FE3CPf7Cad7KsE3H2YKCgoiIiCAnJ+e86ymlKuxji46OZtOmTZSUlFSY15GZmYmPjw8RERF1VrMQQohyqqSkismZzv8/CiePc+zsO5hMEGopbyTadSwfnTh7TkUTC5qPHASgh3rRdJw4cYLDhw9z1VVXVbtOXl4eu3fv5oorrnAtS0pKYt68eWzYsIG+ffsCYLfb2bBhA506dZIjV4QQopYphx21fBEq49ffDzHNhdMnK65k9oEmlvJGIrEbhFlpGNuKfL/fjwhpHIZ2kUcrCvcwXNPx8ssv07JlS1q0aEGDBg04cuQIX375JWazmZtvvhmAOXPm4HA4iI+PJyQkhKysLBYtWoSmaQwaNMj1WLGxsSQnJzN79mzsdjtWq5Xly5eTm5vLww8/rFdEIYQwLLV8EWr+bLA2A0sEWnTLMyMVFis0sULjUDRTxaaigcVCgRfOf6hvDNd0tGnThg0bNvDFF19QVlZGWFgYHTp0YMCAAVitVqB8vseKFStYvXo1RUVFNGzYkMTERIYMGVJpAsyYMWP4+OOP+eSTTygsLKRFixZMmjSJuLg4PeIJIYRhqUP7UYs+hG7JmB6cUC8PKTU6TV3qIRqixrKysqpc7q0zk6tjtDxgvEySx/PV16NXVKkNx/OPQcFpTM9Nv+hLtXtantrgrZnOd/SK951DVQghhOGohe9D1kFMdz1y0Q2H8B7SdAghhNCV+mUbasVitL43oSV217scUYek6RBCCKEbVZiPY9Zr0LQ52uDRepcj6pg0HUIIIXSjPvwfnPoN0z2PofnLCbmMTpoOIYQQunBsWoPatBrt5tvQWrbRuxzhBtJ0CCGEcDt17Cjqw/+DlvFoNw7RuxzhJtJ0CCGEcCtlK8Hxfy+Cw1G+W0XOHlpvSNMhhBDCbZRSqA/+Dw7sLW84mlZ/TgdhPNJ0CCGEcBv17ZeoDd+g/WkYWpeeepcj3EyaDiGEEG6h9mxHzXsHOvdAu3mY3uUIHUjTIYQQos6p43k4ZrwElghMdz+KZpKPn/pI/upCCCHqlCq14ZgxFWw2TGMnoQUG6V2S0Ik0HUIIIeqMUgr14QzYvwfTPY+iNYvWuyShI2k6hBBC1Bm1+ivU+tTyE4B17aV3OUJn0nQIIYSoEyp9F+qTmdAxCe1Pt+tdjvAA0nQIIYSodaqkGMe7/4bGYZjufUwmjgpAmg4hhBB1QM2fDblHMI3+C1pgsN7lCA8hTYcQQohapX7Zhvr2S7SUW9DadtS7HOFBpOkQQghRa1RhAY73XoOI5mgDR+pdjvAw0nQIIYSoNWre2/DbcUyj/4rm5693OcLDSNMhhBCiVqhtm1DrV6LdOBgtrq3e5QgPJE2HEEKIy6ZOn8Ix5w2Iaon2p9v0Lkd4KB+9C6htW7duZfHixWRmZlJQUEBISAjx8fEMHTqUqKgo13r5+fl88MEHbN68GZvNRnx8PKNGjSImJqbC49lsNubOncvatWspKCggNjaW4cOHk5CQ4O5oQgjhsdRHM6AgH9Ojk9F8fPUuR3gow4105OfnExcXxz333MPTTz/NHXfcQWZmJk899RRHjx4Fyk/LO23aNLZu3cro0aMZP348ZWVlTJ48mWPHjlV4vBkzZrBy5UqGDh3KxIkTCQ0NZcqUKWRkZOiQTgghPIsqK8Xx2XuotHVot9yOFtVS75KEBzNc09GnTx9GjhxJr169SEhI4Oqrr+bxxx+nqKiIjRs3ApCWlsauXbsYN24cffr0oUuXLkyYMAGHw8HixYtdj5WRkcG6desYNWoUKSkpdOzYkUcffRSLxcLcuXP1iiiEEB5BZR3E8eLfUMsWoF11PdofBuldkvBwhms6qhIcXH5iGrPZDJQ3HaGhoSQmJrrWCQwMpHv37qSlpbmWpaWlYTabSU5Odi0zm8307t2bbdu2UVpa6qYEQgjhOZRSOFZ+geP5x+B4HqaxkzDdOQ7t9/dYIapjuDkdTg6HA4fDwdGjR/nwww9p3LgxvXv3BiAzM7PS3A2A6Oho1qxZQ3FxMQEBAWRmZmK1WvH3r3jYV1RUFGVlZWRnZxMdLVdMFELUH+rEMRzvvQ47foSOSZhGPYzWKFTvsoSXMGzTMWnSJPbt2wdAREQEzz77LI0aNQLK532Eh4dXuo9zRCQ/P5+AgADy8/Ndy6pbryqpqamkpqYCMHXqVCwWS5Xr+fj4VHubNzJaHjBeJsnj+dyV6VKep3jDKk79dyrYSmj4wN9o8IcBaJpWRxVeHNkWvINhm45x48ZRVFRETk4OS5Ys4fnnn+cf//gHVqsVpVSV9zl3eXXrXUhKSgopKSmu3/Py8qpcz2KxVHubNzJaHjBeJsnj+dyV6WKeRxUVoj6ZifpuJbRojenexyiMiKLwnIn3epJtwXNERkZWe5thmw7n4bFt2rSha9eujB07lkWLFnH//fcTHBxMQUFBpfs4lzlHMoKDg6v8gztHOKoaBRFCCCNRe3fieOffcOwo2h+Hot08DM3HsB8doo7Vi4mkQUFBREREkJOTA5Q3JIcOHaq0XmZmJhaLhYCAAKB8jkdubi4lJSWV1vPx8SEiIqLuixdCCB2oslIcC9/HMW0SAKYnXsQ0YIQ0HOKy1Ium48SJExw+fJimTZsCkJSUxPHjx9m5c6drncLCQrZs2UJSUpJrWVJSEna7nQ0bNriWOX/v1KkTvr5yAhwhhPGoI5k4pk5ALf0ULbk/pudeQ2vdXu+yhAEYrmV9+eWXadmyJS1atKBBgwYcOXKEL7/8ErPZzM033wyUNxPx8fFMnz6dESNGEBQUxKJFi1BKccstt7geKzY2luTkZGbPno3dbsdqtbJ8+XJyc3N5+OGH9YoohBB1QimFWrUU9dks8PPH9NCTaN2u1LssYSCGazratGnDhg0b+OKLLygrKyMsLIwOHTowYMAArFYrACaTiYkTJzJnzhzefvttSktLiY+P57nnnqs0U3jMmDF8/PHHfPLJJxQWFtKiRQsmTZpEXFycHvGEEKJOqN9+PxR254+Q2A3TqEfQGjfRuyxhMJq61EM0RI1lZWVVudxbZyZXx2h5wHiZJI/n0+PoFcfmtagP/g/KStGG3I12zQ0ecyhsTcm24Dnq5dErQgghzk8V5KM+moHatAZaxmO65zG0ptV/YAhxuaTpEEKIeqhk6yYcr/0TTp9Au3U42o2D5TTmos5J0yGEEPWIKilBzX+PE99+Cc2iMY17Cq1Fa73LEvWENB1CCFFPqP2/4nj3Vcg+TOCfbqP4hsFofv4XvqMQtUSaDiGEMDhVVoZaOg/15Txo3ATTY/+k4VXXUuKFkxSFd5OmQwghDExlZ5afxjzjV7RefdFuvx8tUC7hIPQhTYcQQhiIOn0SDu5DHdwHh/ahtn0Pvv6YHpyA1r233uWJek6aDiGE8EJKKTieB4fSUc4m4+A++O2sXSZhVrTuvdEGjZITfQmPIE2HEEJ4OOVwQG6Wq7FQB9Ph0D7IP12+gmaCiOZo8R0gJg4tOq78Z1BDfQsX4hzSdAghhAdRpaXlIxeH9sGB9PKfhzKgpKh8BR8fiGyB1vVKiI5Di4mDqFg0/wBd6xaiJqTpEEIInaiSYsjM+H0Eo3w3SW7WQSgrLV/BPwCiW6L1vrZ85CKmFTSLQvORK1wL7yRNhxBCuIEqyHc1FjhHMrIPg3KUrxDcEKLjCPzTUIoszcobDGszNJNJ38KFqEXSdAghRC1SSsHJ4665F64Jnsdyz6wUaikfuUjqXb57JKYVhFrQNI2GFoucP0MYljQdQghxiZRScDTbNYLhnIfB6ZNnVrJGosW1hWtu/L3BiENr2Ei/ooXQkTQdQghRA8puh+xM1IHyI0fKjyDZD0WF5SuYzdAsGq1j0pkjSKJbojUI1LdwITyINB1CCHEeSinUR/9DrU+FUlv5Qj8/aB6L1vOaM0eQNG+B5uunb7FCeDhpOoQQ4jzUd9+gVi1F63E1dOxePsGzaXO5DLwQl0CaDiGEqIY6mo36+C1o2xHtnkfRTNJoCHE55FgsIYSogrLbcbzzKphMmEb/VRoOIWqBNB1CCFEF9dVnkL4LbfiDaGHhepcjhCFI0yGEEOdQ+/eglnyM1uMaTD2v0bscIQxDmg4hhDiLKinG8far0LgJ2vAH9C5HCEMx1ETSjRs3sm7dOvbt28fJkyexWCz07NmTgQMH0qBBAwByc3MZN25clfefNWsWQUFBrt9tNhtz585l7dq1FBQUEBsby/Dhw0lISHBLHiGE+6l578LRI5jGP48WGKx3OUIYiqGajiVLlhAWFsbtt99OWFgY+/fv59NPP2XHjh3885//xHTWNQwGDBhAUlJShfs7GxOnGTNm8MMPPzBixAiaNm3KsmXLmDJlClOmTCE2NtYdkYQQbqS2bUKt+RrtD4PQ2nbUuxwhDMdQTceECRMICQlx/Z6QkEBwcDBvvvkmO3fuJDEx0XVb06ZNiY+Pr/axMjIyWLduHQ899BD9+vVzPd5jjz3G3LlzmTBhQt0FEUK4nTqWi+O918vPInrrcL3LEcKQDDWn4+yGw6lVq1YAHD9+/KIeKy0tDbPZTHJysmuZ2Wymd+/ebNu2jdLS0ssrVgjhMVRJCY7/vgD2Mkz3/w3NVy4dL0RdMNRIR1V27twJQPPmzSss/+ijj5g5cyb+/v4kJCRw++23ExMT47o9MzMTq9WKv79/hftFRUVRVlZGdnY20dHRdR9ACFGnlFKo2a/Dof2YHn4GLSJK75KEMCxDNx3Hjx9n3rx5dOzY0TXi4evrS0pKCp07dyYkJITDhw+zcOFCnn76aV544QWiosrfcPLz8wkOrjyJzLksPz+/2udNTU0lNTUVgKlTp2KxWKpcz8fHp9rbvJHR8oDxMkmeygoWvE/+5rUEj3iQoH431FJll85dfyPZFjyfITPpXUBdKS4uZtq0aZjNZsaMGeNaHhoayv333+/6vX379nTp0oXx48ezYMECHnnkEeD3S1ZfopSUFFJSUly/5+XlVbmexWKp9jZvZLQ8YLxMkqci9XMajg9moF1xFYVX30iRB7w27vobybbg+bw1U2RkZLW3GWpOh5PNZuOll14iJyeHp556irCwsPOub7FYaNeuHenp6a5lwcHBVY5mOJdVNQoihPAeKjsTx8xXICoWbdQjaJqmd0lCGJ7hmo6ysjJeeeUV9u7dy5NPPllhnsb5KKUqvOlER0eTm5tLSUlJhfUyMzPx8fEhIiKiVusWQriPKizA8eYUMJsxjX0K7Zy5W0KIumGopsPhcPD666+zfft2nnjiifMeEnu2vLw8du/eTevWrV3LkpKSsNvtbNiwwbXM+XunTp3wldntQngl5bDjePsVOJqN6cGJaGFWvUsSot4w1JyOd955h40bNzJo0CD8/f3Zs2eP67awsDDCwsKYM2cODoeD+Ph4QkJCyMrKYtGiRWiaxqBBg1zrx8bGkpyczOzZs7Hb7VitVpYvX05ubi4PP/ywHvGEELVALf4Ifk5Du+NBtLaJF76DEKLWGKrp2Lp1KwALFixgwYIFFW4bPHgwQ4cOJSoqihUrVrB69WqKiopo2LAhiYmJDBkypNLklzFjxvDxxx/zySefUFhYSIsWLZg0aRJxcXHuiiSEqEXqp82opZ+iXXU9Wt8b9S5HiHpHU5dzmIaokaysrCqXe+vM5OoYLQ8YL1N9zqMK83E8Nw6CGmJ66lWPPQGYHL1yaYyWB7w3U707ekUIIc6l5r0Dp05gGv0Xj204hDA6aTqEEIantv+AWr+y/EJuLVpf+A5CiDohTYcQwtBUUSGO99+AZtFofxqmdzlC1GvSdAghDE199h78dhzTqIfRfP30LkeIek2aDiGEYalftqHWfI123S1ordrpXY4Q9Z40HUIIQ1LFRTjmvAHWSLRbh+tdjhACaTqEEAalFr4Px3LLd6v4yWnOhfAE0nQIIQxHbd2I+uYLtH5/RIvvoHc5QojfSdMhhDAUlbkfx9uvQmwbtD+P0rscIcRZpOkQQhiGOn0SxxtToEEgprGTZLeKEB5Gmg4hhCGoslIc//di+VlHxz6F1jhM75KEEOeQpkMI4fWUUqgPZ8CvO9HuegQtto3eJQkhqiBNhxDC66mVS1DrVqD9cSimHlfrXY4Qohoec2l7u91OVlYWBQUFOByOKtdJSEhwc1VCCE+ntv+AmvcudO2FdssdepcjhDgP3ZsOpRRz587l66+/pqioqNr1NE3jk08+cWNlQghPV3b4AI63XobmMZjufhTNJIO3Qngy3ZuO+fPns3Dhwguup5RyQzVCCG+hCvI58dIE8PHBNO5ptIAGepckhLgA3b8WfPvtt3qXIITwQurD/8N+9Aimh55EC7PqXY4QogZ0H+k4ceIEABEREYwePZqIiAjMZrO+RQkhPJrash61eS1Bd9xPcRuZ6yWEt9C96YiMjOTgwYP07t2bLl266F2OEMLDqdMncXw4A1q0JmjQCIp/O6F3SUKIGtJ998qAAQMA+PHHH7HZbPoWI4TweOrDGVBUgGn0X9DMun9vEkJcBN3/xfbu3ZvffvuN999/n3HjxtGtWzdCQ0Or3MUyePBgHSoUQngKx+Z1qC3r0QaMQGveQu9yhBAXSfemo6ioiM2bNwNw8uTJ804slaZDiPpLnTqB+qh8t4p2w5/1LkcIcQl0bzrmzJnDrl27auWxNm7cyLp169i3bx8nT57EYrHQs2dPBg4cSIMGZw6ny8/P54MPPmDz5s3YbDbi4+MZNWoUMTExFR7PZrMxd+5c1q5dS0FBAbGxsQwfPlxOUiaEmymlyudxFBdiuvuvaDLZXAivpHvTsWnTJtf/m0wmQkJC8PG5tLKWLFlCWFgYt99+O2FhYezfv59PP/2UHTt28M9//hOTyYRSimnTppGbm8vo0aMJDg5m4cKFTJ48mWnTphEWduYiUTNmzOCHH35gxIgRNG3alGXLljFlyhSmTJlCbGzs5UYXQtSQSlsHP3yHNuhOtMiYC99BCOGRdG86ysrKAOjSpQvjx4/Hz8/vkh9rwoQJhISEuH5PSEggODiYN998k507d5KYmEhaWhq7du3i2WefJTExEYD4+HjGjh3L4sWLufvuuwHIyMhg3bp1PPTQQ/Tr18/1eI899hhz585lwoQJl1ynEKLm1PG88t0qLePRrh+odzlCiMug+9Erzl0VsbGxl9VwABUaDqdWrVoBcPz4cQDS0tIIDQ11NRwAgYGBdO/enbS0NNeytLQ0zGYzycnJrmVms5nevXuzbds2SktLL6tWIcSFqVJb+eXqS8swjZbdKkJ4O92bjpEjRxIUFMSqVavYv39/rT/+zp07AWjevDkAmZmZleZuAERHR5OXl0dxcbFrPavVir+/f4X1oqKiKCsrIzs7u9ZrFUKcoZRCffB/kPErpnseRWsWpXdJQojLpPvulZkzZxIUFERubi4TJ07EarXSpEkTTOdcuEnTNJ599tmLeuzjx48zb948Onbs6BrxyM/PJzw8vNK6wcHBrtsDAgLIz893LatuPSFE3VHffon6biXazbehde2ldzlCiFqge9PhHIlwys3NJTc397Ift7i4mGnTpmE2mxkzZoxreXUXjjt3+eVcYC41NZXU1FQApk6disViqXI9Hx+fam/zRkbLA8bL5C15bDt+5Ld57+CX1JvGox+u9uqx3pLnYrgrk9FeO6PlAYNm0ruAumCz2XjppZfIyclh8uTJFY5ICQ4OpqCgoNJ9nMucIxnBwcHk5eVVWs85wlHVKIhTSkoKKSkprt+rehwAi8VS7W3eyGh5wHiZvCGPOn4Ux0uTIDyCspHjOPb7fKyqeEOei+WuTEZ77YyWB7w3U2RkZLW36d50XHPNNTVaz+Fw1Gi9srIyXnnlFfbu3cszzzxTaf5GVFQUP/30U6X7ZWZmYrFYCAgIAMrneGzatImSkpIK8zoyMzPx8fEhIiKiRvUIIWpO2Upw/PdFKLVhGvMUWmCQ3iUJIWqR7k1HcnLyBS/0VlZWxuuvv37Bx3I4HLz++uts376diRMnEh8fX2mdpKQkVq1axc6dO11HzhQWFrJlyxb69OlTYb158+axYcMG+vbtC4DdbmfDhg106tQJX1/fmocUQlyQa+Logb2Yxj4lE0eFMCDdm45//etfPPHEE3Tq1KnK20tKSpg2bRrbt2+/4GO98847bNy4kUGDBuHv78+ePXtct4WFhREWFkZSUhLx8fFMnz6dESNGEBQUxKJFi1BKccstt7jWj42NJTk5mdmzZ2O327FarSxfvpzc3Fwefvjhyw8uhKhAffMlasM3aH+6Ha1LT73LEULUAd2bjtLSUl5++WUmTJhQ4dwZUD5/4sUXX2Tv3r01eqytW7cCsGDBAhYsWFDhtsGDBzN06FBMJhMTJ05kzpw5vP3225SWlhIfH89zzz1XacLOmDFj+Pjjj/nkk08oLCykRYsWTJo0ibi4uEsPLISoRKXvQs17G7r0RLv5Nr3LEULUEd2bDjgz8fPJJ5907fL47bffeP7558nMzATKD5m9kDfffLNGzxccHFzhiJbq+Pn5MWrUKEaNGlWjxxVCXDxlK8Ex6zUItZSfAKyaI1WEEN5P93/dzvkSNpuNqVOnsmvXLrKzs3nmmWdcDYfZbGbs2LE6VimEqCtq0QeQcxjTqIdl4qgQBqf7SMdDDz2Ev78/y5Yto6SkhBdffBE/Pz9OnToFQEBAAI8//jgdO3bUuVIhRG1Te3eiUj9H63sjWvvOepcjhKhjujcdAHfffTf+/v58/vnnFBcXu05F3rhxY5588km5oqsQBqRKft+t0iQc7c936V2OEMINdN+94jR8+HCGDBni+r158+ZyCXkhDEwteh9yj2C66xG0gAZ6lyOEcAO3j3TcdlvNZqYfPny4wjwOTdP45JNP6qosIYQbqT07UCuXoPW7Ca1d1YfLCyGMx2NGOi7kcq6FIoTwHKqkGMd7r0GYFW2QHBkmRH3iNU2HEML7KYcdNf89OJotu1WEqIfcvnvloYcecvdTCiF0oEpLIesA6uA+OJhe/jMzA2wlaP3+iNZWjkgTor5xe9PhPC+HEMI4VHEhHNyPOrQPDu4rbzCOHAS7vXyFBoEQHYd29R+gRWu0pD7nf0AhhCF5xCGzQgjvoU6fPNNYOEcwjh4B57yrkMYQE4fWKQktJg6i48DSVM40KoSQpkMIUTWlFBzPczUWzlEMfss7s1KYFVq0QruyX3mDEdMKrXET/YoWQng0aTqEECiHHXKOoA6mwyHnKMY+KDhdvoJmgojmaPEdyhuL30cwtKBgfQsXQngVaTqEqGdUWSlkHUQdOKvByMyAkvIzAePjA81j0bpdWb6bJDoOolqi+fvrWrcQwvtJ0yGEganiIsjc7xq5OJZ1AMfB/WAvK1/BvwHEtETrc135yEWLOIiIRvORtwYhRO2TdxYhDELln/p9gmd6+c9D+yAn68wEz4aNMLVqi3Z9J4j+fRdJeIRM8BRCuI00HUJ4IeWww/YfUBl7f5/gmV4+6dOpSXj53Ise17gmeNK4CaHh4eTl5VX/wEIIUYek6RDCC6lP30OlLgZNg6bN0VonlM+/iGkF0S3RgkP0LlEIISqRpkMIL6P2bEet/BztquvRht4jpxIXQngNaTqE8CKquAjHrNfKT7Z1271o/gF6lySEEDUmM8iE8CJq/ntwLBfT6L9KwyGE8DrSdAjhJdTOrahVX6Gl3ILWJkHvcoQQ4qJJ0yGEF1CFBThmvw4RUWgDRuhdjhBCXBLDzek4duwYixcvJj09nQMHDmCz2XjjjTewWq2udXJzcxk3blyV9581axZBQUGu3202G3PnzmXt2rUUFBQQGxvL8OHDSUiQb5rCfdS8d+C345gmvoTmJ2cGFUJ4J8M1HdnZ2WzYsIG4uDjat2/Ptm3bql13wIABJCUlVVjWoEHFIwFmzJjBDz/8wIgRI2jatCnLli1jypQpTJkyhdjY2LqIIEQFattm1PpUtBsHo8W11bscIYS4ZIZrOtq3b8/MmTMBWLly5XmbjqZNmxIfH1/t7RkZGaxbt46HHnqIfv36AZCQkMBjjz3G3LlzmTBhQu0WL8Q5VMFpHO+/Ac1boP3pdr3LEUKIy2K4OR2mWjylc1paGmazmeTkZNcys9lM79692bZtG6WlpbX2XEKcSznsON75N+SfwnT3X9F8ffUuSQghLovhRjouxkcffcTMmTPx9/cnISGB22+/nZiYGNftmZmZWK1W/M+5umZUVBRlZWVkZ2cTHR3t7rJFPaEWvA8/p6ENf7D8TKNCCOHl6mXT4evrS0pKCp07dyYkJITDhw+zcOFCnn76aV544QWioqIAyM/PJzg4uNL9ncvy8/PdWreoPxwbvkUtW4DW90ZMfW/SuxwhhKgV9bLpCA0N5f7773f93r59e7p06cL48eNZsGABjzzyCADKeXXOi5SamkpqaioAU6dOxWKxVLmej49Ptbd5I6PlAX0yle7ZwfH338Q3sRuhY5+s1cvMG+1vZLQ84L5MRnvtjJYHDJpJ7wI8hcVioV27dqSnp7uWBQcHV3lFTucIR1WjIAApKSmkpKS4fq/uqp4Wi8VQV/w0Wh5wfyZ1PA/HC09A4ybY73mMYydO1OrjG+1vZLQ84L5MRnvtjJYHvDdTZGRktbcZbiLp5VBKoWma6/fo6Ghyc3MpKSmpsF5mZiY+Pj5ERES4u0RhYKqkBMd/X4CSYkxjn5YrxQohDEeajt/l5eWxe/duWrdu7VqWlJSE3W5nw4YNrmXO3zt16oSvHE0gaolSCjX7dTiYjunex9Gax1z4TkII4WUMuXtl48aNAOzbtw+ArVu3EhISQkhICAkJCcyZMweHw0F8fDwhISFkZWWxaNEiNE1j0KBBrseJjY0lOTmZ2bNnY7fbsVqtLF++nNzcXB5++GFdsgljUks/RW1eizZoFFrnK/QuRwgh6oQhm45XX321wu9vv/02UH5ir7///e9ERUWxYsUKVq9eTVFREQ0bNiQxMZEhQ4ZU2hc1ZswYPv74Yz755BMKCwtp0aIFkyZNIi4uzm15hLGprRtRiz5A69UX7YZBF76DEEJ4KUM2HfPmzTvv7f3796d///41eiw/Pz9GjRrFqFGjaqM0ISpQSuGY+w7ExKHdOa7CnCIhhDAamdMhhJ4O7IW8HLR+f0Tz9dO7GiGEqFPSdAihI5W2HsxmtK699C5FCCHqnDQdQuhEKYXash7adUILaqh3OUIIUeek6RBCLwfTy3etdO+tdyVCCOEW0nQIoROVth5MJtm1IoSoN6TpEEIHZ3atdJYzjwoh6g1pOoTQw6F9cDQbLUl2rQgh6g9pOoSoRY7Uz1EZv15wPdeulS6ya0UIUX9I0yFELVE5Wai5b+P4z99ROVnVr3f2USsNZdeKEKL+kKZDiFqitm36/X8cOKb/E1WQX/WKh/ZD7hE5akUIUe9I0yFELVHbNkHzFpjGPQPHcnDMmIoqK6u83hY5akUIUT9J0yFELVAFp2HvTrTOPdHaJKDd+TDs+gn18f9QSp1ZT6ny+RxtO6I1bKRjxUII4X7SdAhRC9TPW8DhcF2W3nRlP7SbhqLWLEOlfn5mxcwMyM2SXStCiHrJkFeZFcLtftoMIY0hto1rkXbrHaicTNSn76KszdA69ygf5dBk14oQon6SkQ4hLpMqK0Vt34LW6Qo005l/UprJhGn0oxDTCsfMf6EO7S+fz9E2ES2ksX4FCyGETqTpEOJy/boTigpdu1bOpvn7Yxr3NAQG43j1acg5LLtWhBD1ljQdQlwmtW0T+PpB+y5V3q41blLeeJSWlu9a6XalewsUQggPIXM6hLgMSqnypqNdJzT/gGrX02LiMP3l76jcLNm1IoSot2SkQ4jLkXWw/PL0nXtccFWtTQKm3iluKEoIITyTNB1CXAbnWUi1TpXncwghhKhImg4hLoPatglatEYLDdO7FCGE8HjSdAhxidSp32D/nhrtWhFCCGHAiaTHjh1j8eLFpKenc+DAAWw2G2+88QZWq7XCevn5+XzwwQds3rwZm81GfHw8o0aNIiYmpsJ6NpuNuXPnsnbtWgoKCoiNjWX48OEkJCS4M5bwQOqnNFCqykNlhRBCVGa4kY7s7Gw2bNhAcHAw7du3r3IdpRTTpk1j69atjB49mvHjx1NWVsbkyZM5duxYhXVnzJjBypUrGTp0KBMnTiQ0NJQpU6aQkZHhhjTCk6ltmyHUAtFxepcihBBewXBNR/v27Zk5cyZPPvkkvXpVfarptLQ0du3axbhx4+jTpw9dunRhwoQJOBwOFi9e7FovIyODdevWMWrUKFJSUujYsSOPPvooFouFuXPnuiuS8ECq1AY7f0TrfAWapuldjhBCeAXDNR0m04UjpaWlERoaSmJiomtZYGAg3bt3Jy0trcJ6ZrOZ5ORk1zKz2Uzv3r3Ztm0bpaWltVu88B67fgJbCVonmc8hhBA1ZbimoyYyMzMrzd0AiI6OJi8vj+LiYtd6VqsVf3//CutFRUVRVlZGdna2W+oVnkf9uBH8A6BdR71LEUIIr1Evm478/HyCgoIqLQ8ODnbd7vzpXHa+9UT9orZtQq1bgdbjajRfP73LEUIIr2G4o1dqQilVo+XVrXchqamppKamAjB16lQsFkuV6/n4+FR7mzcyWh6onKnsQDrH334Vn5bxNBk78bynPvdERvsbGS0PuC+T0V47o+UBg2bSuwA9BAcHU1BQUGm5c5lzJCM4OJi8vLxK6zlHOKoaBQFISUkhJeXM6a6regwAi8VS7W3eyGh5oGImdfokjinjwd8fxwMTOHY6H05712iX0f5GRssD7stktNfOaHnAezNFRkZWe1u93L0SFRXFoUOHKi3PzMzEYrEQEFD+7TU6Oprc3FxKSkoqrefj40NERIRb6hX6U2WlOGZMhZO/YRozCa2Jsb59CCGEO9TLpiMpKYnjx4+zc+dO17LCwkK2bNlCUlJShfXsdjsbNmxwLXP+3qlTJ3x9fd1at9CHUgr14QzYswPtrkfQ4trqXZIQQnglQ+5e2bhxIwD79u0DYOvWrYSEhBASEkJCQgJJSUnEx8czffp0RowYQVBQEIsWLUIpxS233OJ6nNjYWJKTk5k9ezZ2ux2r1cry5cvJzc3l4Ycf1iWbcD+1ckn5xNGbhmDqeY3e5QghhNfS1KXOlvRgQ4cOrXJ5QkICf//734HyeRlz5sxh8+bNlJaWEh8fz5133klsbGyF+9hsNj7++GPWrVtHYWEhLVq0YPjw4XTo0KHG9WRlZVW53Fv311XHaHkAGh7cy4nnH4fOPTA9NBGtBueB8WRG+xsZLQ/InI5LZbQ84L2Zzjenw5BNh6eRpsM7qSOZqKl/QzUJxzThJbSABnqXdNmM9jcyWh6QpuNSGS0PeG8mmUgqxEVSxUU43vgn+PhiGve0IRoOIYTQmzQdQlRBLfoAjmbT+G9T0MKsF76DEEKIC5KmQ4hzqPRdqG++QOt7I36JXfUuRwghDEOaDiHOospKccx5AxqHoQ26U+9yhBDCUKTpEOIs6qv5kHUQ04iH0AIC9S5HCCEMRZoOIX6nsg6ivpxXfiG3TlfoXY4QQhiONB1CAMrhKN+tEtAA7bZ79S5HCCEMSZoOIQC1+itI34U29B60kMZ6lyOEEIYkTYeo99Sxo6j5cyChK9qV/fQuRwghDMuQ114R4lxKKTh9EnKzUDlZkPP7z9zf/0PDNHIMmqbpXaoQQhiWNB3CUFRhPuQcQeVmQc7h8v/POQy5R6Co4MyKZjOER4A1Eq1dZ7RuV6JZmupXuBBC1APSdAivo0pK4OhZoxU5Wb83GVnloxlOmgZNwqFpc7Re8eU/rZHQNBLCrGhms34hhBCiHpKmQ3gkVVYKR3N+3x1yzojFb+dcAKlRE2gaidalZ/nPppFgjYTwCDRfP30CCCGEqESaDqEb5bDDsaMVRipcIxZ5uaAcZ1YOblg+UtGuY3lD0bQ5WtNmYG0mJ/ESQggvIU2HqFNKKThxvOoRi6NHoKzszMr+DcpHKmLbQM9ryudbNC3fHaIFNdQvhBBCiFohTYe4bEopyD+NLe8Ijj07y0cqnPMtjh6BkuIzK/v4grUZRDQvP+unc3dI0+YQ0liOHhFCCAOTpkPUmCoqLB+xyP59pCLnMOr3nxQW8JtzRZMJLBHlDcXvu0OcIxaEWtBMcnoYIYSoj6TpEJUoux1+3ow6klnxfBanTpxZSdMg1FLeWPS4GppG0qh1O041aFh+ZIiPbFpCCCEqkk8GUYn6ZCZq1dLyXxqFlk/W7HRFxRGL8Ag0P/8K9/O3WNDy8qp4RCGEEEKaDnEOtWcHatVStH43oQ28E62BHBkihBCidkjTIVxUqa38SquWpmh/vgvNP0DvkoQQQhiIzOgTLuqLuZBzGNPIsdJwCCGEqHX1dqRjx44dTJ48udLywMBA3nvvPdfv+fn5fPDBB2zevBmbzUZ8fDyjRo0iJibGjdXWPXVoP2rZArTka9ESuuhdjhBCCAOqt02H0+jRo2nVqpXrd/NZ1+NQSjFt2jRyc3MZPXo0wcHBLFy4kMmTJzNt2jTCwsL0KLnWKbsdx+zpENQQbejdepcjhBDCoOp909G8eXPi4+OrvC0tLY1du3bx7LPPkpiYCEB8fDxjx45l8eLF3H23MT6gVerncGAvpgeekDN/CiGEqDMyp+M80tLSCA0NdTUcUL77pXv37qSlpelYWe1RuUdQn38IXXpC9956lyOEEMLA6v1Ix/Tp0zl16hRBQUF07tyZ4cOHY7FYAMjMzKxy7kZ0dDRr1qyhuLiYgADvnXCpHA4c778JZh9MdzwopyAXQghRp+pt0xEYGMjNN99MQkICgYGB7N+/n4ULF/LUU08xbdo0GjVqRH5+PuHh4ZXuGxwcDJRPMvXqpmPxR7DrJ7Q7x6GFGmN+ihBCCM9Vb5uOli1b0rJlS9fvCQkJtG/fnkmTJvHVV18xbNiw8guZVaG65U6pqamkpqYCMHXqVNfIybl8fHyqva2uFa1Zzqml82hw3S00HHB7rYxy6Jmnrhgtk+TxfO7KZLTXzmh5wKCZ9C7Ak8TFxdGsWTPS09OB8hGNgoKCSus5lzlHPM6VkpJCSkqK6/e8ak4NbrFYqr2tLqn9e3BMnwLxHSgZNArbsWO18rh65alLRsskeTyfuzIZ7bUzWh7w3kyRkZHV3iYTSc8jKiqKQ4cOVVqemZmJxWLxyl0r6ngejjenQKNQTA8+iebjq3dJQggh6glpOs6Snp5OVlYWbdq0ASApKYnjx4+zc+dO1zqFhYVs2bKFpKQkvcq8ZKqkBMd/X4DiYkwPP4PWMETvkoQQQtQj9Xb3yuuvv47VaqVly5YEBQWxf/9+Fi1aRJMmTbjhhhuA8qYjPj6e6dOnM2LECIKCgli0aBFKKW655RadE1wcpRTqvdfgYDqmsU+jNW+hd0lCCCHqmXrbdERHR7N+/Xq++uorbDYbjRs3pkePHgwdOpSQkPIRAJPJxMSJE5kzZw5vv/02paWlxMfH89xzz3nd5B715VxU2jq0wXehdb5C73KEEELUQ/W26Rg4cCADBw684HrBwcGMGTPGDRXVHbXlO9Tij9Cu7Id2/YUzCyGEEHVB5nQYnDq4D8e7r0Krdmgjx8oJwIQQQuhGmg4DU6WlON5+BQIbYnroSTRfP71LEkIIUY9J02Fg6su5cOQQpjvHoTUK1bscIYQQ9Zw0HQalDu1HfT0frVc/tI7d9S5HCCGEkKbDiJTdjuO91yEwGO22e/QuRwghhACk6TAktXxh+fk4hj+IFiwnABNCCOEZpOkwGJWdifr8Y+h2JVr33nqXI4QQQrhI02EgyuHAMXs6+PljuuNBvcsRQgghKpCmw0DUt0th7y9ot90jR6sIIYTwONJ0GITKPYJaOAcSu6Fd2V/vcoQQQohKpOkwAFVcWH65erMPphFy1lEhhBCeSZoOL6ccDhzv/geyMzE9OAEtLFzvkoQQQogqSdPh5dQXc+HHjWhD7kZr31nvcoQQQohqSdPhxdQP36GWfIyWfC3atX/SuxwhhBDivKTp8FIqM6N8t0rLeLQRD8k8DiGEEB5Pmg4vpPJPlU8cDQjENEauHiuEEMI7SNPhZZTdjuN/0+DE8fKGo3GY3iUJIYQQNSJNh5dRn74Lu35CGzkWLa6t3uUIIYQQNSZNhxdxrE9FrVyClnIrpmQ5AZgQQgjvIk2Hl1BKodLWQ/vOaIPv0rscIYQQ4qL56F2AqBlN0zCNfQpKbWhms97lCCGEEBdNmg4vovn4gI/8yYQQQngn+QSrgby8PGbPns1PP/0EQMeOHbnrrruwWCw6VyaEEEJ4D5nTcQElJSX84x//ICsri7FjxzJu3DiOHDnC5MmTKS4u1rs8IYQQwmvISMcFrFy5kpycHF577TUiIiIAaNGiBY888gipqancfPPNOlcohBBCeAcZ6biAtLQ04uPjXQ0HgNVqpW3btmzevFnHyoQQQgjvIk3HBRw6dIjo6OhKy6Ojo8nMzNShIiGEEMI7SdNxAfn5+QQFBVVaHhwcTEFBgQ4VCSGEEN5J5nTUQFVXcFVKVbt+amoqqampAEydOrXao1x8fHwMdQSM0fKA8TJJHs/nrkxGe+2MlgcMmknvAjxdcHAw+fn5lZYXFBRUOQICkJKSQkpKiuv3vLy8KtezWCzV3uaNjJYHjJdJ8ng+d2Uy2mtntDzgvZkiIyOrvU12r1xAVFQUhw4dqrQ8MzOTqKgoHSoSQgghvJM0HReQlJTEr7/+Sk5OjmtZbm4uu3fvJikpScfKhBBCCO8iTccFXHvttYSHhzNt2jQ2b95MWloaL7/8MmFhYVx33XV6lyeEEEJ4DU2db0akAMrnZLz33nv8/PPPKKVITEzkrrvuwmq16l2aEEII4TVkpKMGLBYLjz/+OLNnz2bOnDk88cQTtdJwTJw4sRaq8xxGywPGyyR5PJ+7MhnttTNaHjBmJmk6hBBCCOEW0nQIIYQQwi2k6dDR2efyMAKj5QHjZZI8ns9dmYz22hktDxgzk0wkFUIIIYRbyEiHEEIIIdxCmg4hhBBCuIU0HUIIIYRwC2k6RL2SmZnJnDlz9C5DnEdubq5XXuRK1D7ZFoxHrjJbC2w2G6tWrSI4OJjmzZvTvHlzfHx8cDgcmEze2dfZbDa++eYboPzkaK1bt6Zx48Zem6mkpISZM2eydu1aAPr06UNcXBxKKTRN07m6i2ez2fj1119p3769V/49qlJSUsJbb73FunXrmDBhgtdf0ttd7wuyLXg+I35GXCppOi7TN998w+zZswkJCaGwsJCysjJ69uzJmDFjvHZjWrp0KfPnzyckJISSkhJ+++03unfvzuOPP+6VmRYtWsSnn35Kq1atuPHGG1m5ciW5ubnExcV5ZcOxZs0a3nrrLSwWC2PGjCE+Pl7vki7b4sWLmTdvHjExMTzxxBN06tRJ75Iui7veF2Rb8HxG/Iy4HNJ0XIb9+/ezcOFCbr31Vvr06UODBg347LPP+Prrr/Hz82P48OE0aNBA7zJr7MSJE7z77rscOHCAP//5z3Tr1o3g4GAWLlzIN998ww8//EC3bt30LrPGdu3axUsvvYS/vz8jR46kb9++nDp1ihUrVnDixAkAr/qmUVJSQmpqKsuWLSM6OpqMjAw2b95MTEwMAQEBXjlqk5OTw4svvkhubi733XcfSUlJBAcHe12Os7njfUG2Be9gtM+I2uAd77Yeau3atRQXF5OcnIzVaqVhw4bceuutXHPNNaxcuZL169dTWlqqd5k1ZrfbOXnyJEOGDOH666/HarUSHBxMjx49sNls+Pn56V1ijdlsNtLT0+nbty///Oc/ueGGG1xvxo0bN2bnzp0AXtNwAGiaxqpVq7BYLDz55JNcddVVrFy5kl9++cV1u7cJCgri9OnTtG7dmrZt29KwYUM0TaOgoIBTp05ht9td6zocDh0rrTl3vC/ItiDbgreSkY5L4Px2XFhYSEhICBERESilUErRpEkTOnXqxOrVq1m7di2tW7cmNjZW75JrJCwsjHvuuYeYmJgKy0+fPk18fDxWq5WysjJ8fHw8/puUn58f119/Pb6+vhWWN23alMDAQAoKCigqKvKabxkOhwM/Pz8eeOABWrduDcDIkSNZv349q1evpmXLljRu3Njj/y5ns9vtBAcHM3ToUD755BO2bdtGZGQks2bNYuvWrZhMJqxWK1dffTW9e/f2+Fzuel+QbUG2BW/mPV/zdPT999+zbt06fvnlF5RSmEwmHA4HkZGRZGZm8ssvv6BpGmVlZUD5hzeUD+9v374dAE878WtGRgYFBQVAxdrObTg+//xz/v3vf3P48GEmTJjAyy+/TEZGhsf9o68qz7kNh/PbUYcOHTh06BABAQHuLfIi7Nixgz179nDo0CHgzIiM80PGZrPRsGFDhgwZwsaNG9m2bRvg2d9wz81kNpsB+MMf/kBUVBQLFizgvvvuY/v27fTq1YuOHTuSlZXF66+/zo8//uhx2ar6G9XF+0JV7z/g3dvCuZm8fVsw4mdEXZHToJ9HZmYmr732GsePHyc4OJjs7GySk5MZOHAgMTEx/PLLL7z99tv4+PjwwgsvuP7hfPTRR2RlZaFpGllZWbzyyis6JznjwIEDvPnmm+Tk5PCXv/yl2jkaDoeDb775hrlz53LDDTfQtm1bMjIyWLFiBSaTiX/961+uvHqqaZ6zzZ8/n/nz5/P000+TkJDghiprbvfu3bz77rsUFhZSWFhIfn4+f/7zn7n++usrfHs9+1vs2LFjCQsL44EHHqB58+YeN0/lQpkAtm3bxhtvvEH//v254YYbCAkJwWw2s2/fPmbPns3p06d59dVX9Q3yu+ryXHfddYSGhvLLL7/wzjvvYDabL+t9obr3nz//+c9ERUV55bZwoUwAW7du5c033/SKbcGInxF1TXavnMeCBQto0qQJjz32GEFBQWzevJmFCxfy2muvMXXqVNq3b88f//hH5syZw6OPPkpiYiJHjhxhz549jB07lpMnT7Jv3z5ycnJo2rSprlmUUmzZsoX58+e79iGuWbOGli1bEhoaWml9k8lEt27d6NGjByEhIQAkJibSqFEj3njjDbZs2UKPHj10G8K92DxwZsizVatW2O12bDabO0s+L4fDwbfffsvChQtJTEx0XehpzZo1LFmyhODgYG666SbXa61pmivPqFGjeOWVV9i8eTPNmjXDZDJ5xNB6TTMBdO7cmdtvv52EhIQKf7+YmBiuvPJKZs2axfbt20lMTNQlC9Q8T/v27bnpppsu+32huvef//znP0yZMgV/f3/AO7YFp/Nlev755wkICKBLly4MGzaMDh06eOy24GSkzwh38ZwW2MMcOXKEn3/+mfbt29OsWTNCQkK49tprufPOO8nLy3OdYKp///5MmjSJVq1asXPnTho1asQ///lPkpOTCQoKwmQyER4ernOa8jemTZs2kZmZyejRoxkxYgQbNmzg559/rnZSVpMmTVwNh3NArFmzZpjNZteuDL3ezC4lj/MbX2RkJAEBAezbtw/wjElpubm5rF+/nsTERIYPH07r1q1p3bo1o0ePplGjRuzZswe73V5hCNaZp0ePHiQkJLBy5Up+/fVXbDYbW7dudR2ho5eaZnJOEOzfvz8REREArv3fPj4+rjdjvQdla5LH2QD369fvst4Xzvf+c/ToUT788MMKExA9fVuAC2f66KOPKCkpAeDaa6/16G0BjPcZ4S4y0lENpRT5+fnExcUBuCZQdunShVtvvZXPPvuMXr16kZCQQHx8PK1bt6asrMx1hMepU6dYu3YtzZs3B/Q9NNP53MOGDWPw4MFYrVYcDgerVq3i66+/pnXr1kRGRla639nfkDRNo7i4mLS0NMLCwnTdLXGpeZw0TSM4OJiMjAzsdrtH7CYymUx06NCB6667joYNGwJntrnY2FiOHDlSZZ3O+u+77z4effRRli5dilKK77//nrvvvps//OEP7o7icimZHA4Hmqa5truioiK+//57LBYLzZo1c3uGs9Ukz9nziC7nfeFC7z/z58+nZ8+edOjQwXUfT94W4OIzefK2AMb6jHAn4ye8RA0bNiQsLIyNGzcCZ75J+Pn5cfXVV9OsWTO+/PJL1z5Vk8mEn58fRUVFnDhxgm+//ZacnByuv/56TCaTrhuT87lDQ0OxWq3Y7XbXh3Z6ejqbNm2qcleD8x97SUkJJ06c4JtvvuG7776jb9++hIeH6/Zt41LzOIWHhxMREcGJEycwm80e8a3JarVy6623EhIS4hp58fEp/05w7Ngx1xvTubWazWZKS0sJCQkhOjqajRs3cujQISZMmKD7h8ylZDKZTK4G9/jx46SmprJlyxauu+461+Q7vVxMHue/nUt9X7jQ+09ERARffvml6/nAs7cFuPhMnrwtgLE+I9xJRjqq4evrS7t27di2bRvZ2dlERES4vkmEhoZy7bXXMnv2bNdtSilycnJYunQp6enpZGZmMmLECI86mZbzjdD57bJjx44kJyezbNkyOnToQJs2bSqs73A4+P7779m6dSsHDhwgOzubO+64g+uvv97ttVflYvPAmQ+ERo0asWPHDo86/4jzA+zsN5/i4mJOnTpF9+7dgcq7s8rKyvjxxx95//33OXHiBPfdd59rroEnuNhMSik2b97Md999x5EjR8jOzmbYsGHceOON7i28GpfyN8rOzr7o94VLef+x2+0evS1cbCa73c6WLVs8dlsw4meEO9SP1uoiKaUICAigc+fOOBwOvv76awDXt2Kz2UxcXBwhISFs2rQJKH+jiYiIIDAwkC5dujBz5kyuu+46PWPUyNChQykoKGDVqlXk5+dXur2srAybzUaXLl146623PKbhqM6F8jg/EG666SbeeOMNj2k4zuX89pqdnU1eXp5rCPdcPj4+HDhwgK5du/LOO+941IfMuWqSyblOWVmZ69+Rp3zInKumf6OLfV+41PcfT94WLjWT8zBTT9sW6tNnRG2rVyMdP/30E7m5uTRp0oR27doRGBhY5XoOhwOz2cyVV17J999/z+bNm+nWrRudOnXCbrfj4+ND69atsdlsBAUFAWf2pw4ZMsStcwRqmqm6GezNmjXjj3/8I1988QVXXHEFCQkJHDx4kICAAKKioujRowdXXHGF285pUVd5GjRoQPPmzV37XZ3nOKhrl5tnz549BAUFVTh50KlTp3A4HK7DTQcOHOj6Bu4OdZ2pS5cudOrUyWu2uZr8jYYMGcLPP//M8uXLCQsLo0OHDq5J2ue6lPcf53wAd28LW7duJTMzs04ymUwmunbtSseOHd22LdRlHr0+IzxNvWg6jh07xn//+1/27t2LxWIhMzOT1q1bM3DgQJKSkiqs69yYoPxb5K233spbb73FrFmzeOGFF1xnsNyzZw8+Pj6uNxXnfdy1MV1sJudwcGlpKb6+vhWW3Xrrraxbt44lS5awfft2vvjiCxISEnj22Wddh+V5e54OHTrwzDPPuO0N+XLzOD/g9u3bR1RUFI0bN6a4uJjvvvuOhQsX0rNnT0aMGAFguEzuGn1yV55Tp07x5ptvsmvXLqKioti7dy8tWrRg0KBB9OrVq9LzXMr7j7M2d20L7sjkXN8dmdyRx92fEZ6qXpwcbMaMGRw6dIi7774bi8XCgQMHmD17NseOHePpp5+mVatWFb7BFBUVMWfOHJo1a8Ytt9zC999/z7vvvkuTJk3o2rUrLVq04PPPP8dsNvO3v/3NNZPd0zO9//77WK1Wbrnllgr7pAsKCvjoo49ITU3Fx8eHQYMG8ec//1ny6JzHZrMxadIk4uPj6d+/P7NmzWLfvn0MGDCA2267za15jJjJXXk+//xz1q9fz3333Ufz5s05ePAg8+fPZ9euXTz11FPEx8d73fuP0TIZLY8nM/ScDqUUR44cYcOGDXTu3JlWrVrRqFEjOnXqxJAhQ9A0jblz53LkyBHXfRYvXsz999/Pnj17aNeuHQA9e/bkySefJCQkhPXr1zNnzhwsFgsTJkxw+8Z0OZl2795NYmJihQ/offv2MX36dFJTU+nXrx9vvfWWWz+gJU/lPM43t9zcXHJycti0aRNPP/00jRs3ZubMmW7/cDZaJnflUUphs9n44YcfCAsLo3Xr1jRo0IC2bdty991306xZM+bMmeN17z9GymS0PN7AsLtXnEOfzm8jrVq1AnAdrZCYmEhMTAw//fQTW7duJSIignXr1rFy5UpGjhzJVVdd5RomU0oRGxvLhAkTyM/Pp6ysjCZNmnh1JqesrCxKSkqYMmWK2+Y5SJ6a5Tl58iSaphEZGcmoUaNcjyeZvCOPcyJkXl4ePXv2BM7s14+IiGDUqFFMnjyZjRs3MmDAANavX+/R7z9GzGS0PN7AME1HXl4eP/zwAxaLhbi4ONd+tNLSUpo2bcrXX39N9+7d8fPzo6ysjODgYNe+45UrV9K3b1+Sk5Pp2rVrpc707GPuq5tY5G2ZnG++ffr0oU+fPpLHg/I4s8TFxfH0008THx/vljxGzOSuPE2bNq10tJTD4cDX15dWrVrx008/ARX35yckJHD11VezYsUK1/N06dLFY95/Tp48SX5+vuv8I+DdmYyWx1sZYvfKvHnz+Mtf/sJXX33FK6+8wnPPPcfnn38OlB/NkJSUxPbt21m3bh1QPvnnyJEjnD59mmHDhnH48GF++eUXfHx8XDON9VbXmdx9+nLJU/M8ziwNGjRwa8NhtEzuyvPTTz9x//33s3jxYk6dOgWcObkVlF/V+ODBg6SlpQG4TvsOcOONN3Ly5Em2bt2K2Wz2mPefzz77zFCZjJbHm3n9SMf27dtZu3YtDzzwAImJiZSWlvL+++/z0UcfERISQt++fenXrx9ZWVlMnz6d9evXExYWxurVq+nQoQNJSUmsXbuW9PR0unfv7hFnhTNaJsnj2XmMmMkdeU6cOMFnn33Gjz/+SLNmzVwXQUxKSqpwEba2bdsSFxfH/PnzSUpKwmw2u24LCwujVatWfP/99/Tv31/3181omYyWxwi89tVzHnSzZcsWoPwqlU2aNKFp06aMHDmS5ORk3n//fQ4ePEjz5s157LHHGDhwIMXFxezevZvhw4czceJEoqOjKS4uxmKx6BkHMF4myePZecB4mdyZp6CggBUrVtC1a1eeeOIJQkJCWLZsGXl5ecCZ0ZAWLVrQq1cvDh8+zKJFiyrU2ahRIzRNIzAw0CMuPGi0TEbLYwReO9Lh3FhOnDhB48aNadSokevET02bNmXAgAHs2rWLBQsW8OCDDxIQEMCwYcMoLi52nWjGeZrvoqIi1xUN9WS0TJLHs/OA8TK5K49SiubNm/PMM8+4LrE+ePBgXn/9dbZu3Urfvn3x8fFxfVvu06cPBw4cYN68ebRp08Z1UbNjx45x+vRpOnbsqPs3aKNlMloeo/DaV9DZhbZu3Zr09HROnDjh2oAAoqKiuPnmm/n+++85ePCg6z7ON5aCggL27t3L8uXL6dy5s+vQJz0ZLZPk8ew8YLxM7s7j/DBzOBwkJyeTmJjIV199RVZWFnDmpF1hYWEMHDiQ9u3b8+qrr/LGG2+wZs0aZs6cic1m44orrqj9F+MSGS2T0fJ4O69tOpzfaJo2bUrDhg1dVyc8exZxt27dsFqtrvPiO9+Qli1bxjvvvMOUKVPw8fHhzjvv9IgO1miZJI9n5wHjZXJXnnMnLjuviDps2DCysrL47rvvKC4uBnA1PNHR0fztb3+jb9++HDp0iM8//xy73c6zzz5b4RTqejFaJqPlMQqv3b3iPGQtISGB2NhY0tLSuOqqq4iJiXEdZ924cWMSEhLYuXMnp06dch3KFBMTw/79+xk/fjydOnXSOckZRsskeTw7Dxgvk9552rRpQ79+/VixYgWdOnUiISGhQuMSEBDAyJEjKS0t5fTp015xLgejZTJaHm+j/1etcxQXF7Ns2TI2bNjAoUOHKCsrA6g0gcd59cHAwECuuuoqSkpKXBOAnFf6CwgIcB1PHRAQ4PpG0759ex588EG3vVEaLZPk8ew8Rszkrjx33XWX62yl53ue6pYBDBo0CIBvv/2WkydPcurUKX788ccK6/j6+rrtw6ymr111y8CzMhktT33jUSMdy5cv54MPPqBRo0YUFBSglKJXr1488MADFTpR58Qf54WA+vTpw969e1m5ciVff/01N9xwA5qmYbPZyM7Oxmq1us48J5kkj5HzGDGTu/Jc7POcu+vFOcpisVgYOHAgc+fOJSwsjL179/Lzzz/z4osvEhcX54ZX7AyjZTJanvrIY5qOvXv3snjxYgYPHkyvXr0ICAhg3rx5rFixAn9/f4YNG0ZAQECFqz1+9913bNy4kZEjR3LzzTdjs9mYNWsWBw8epF27dmRlZfHzzz8zevRofH19JZPkMXQeI2ZyV55LfZ7NmzczcOBAYmJiXM1LaWkprVu3xm63s3DhQtq1a8fUqVNp2bKlV7x2nprJaHnqK49pOlatWoXD4eDKK68kPDwcgAEDBlBYWMiKFSuIjY2ld+/e+Pr6cvDgQf73v/+5rubYsGFDAgICuPfee2ncuDGbN29m586dKKV44IEHKl2aWDJJHiPmMWImd+W51OcZOHAgVqvV9TiFhYWsXLmSRYsW0ahRI+677z66devm3hfNoJmMlqe+0r3pcA53FRUV0ahRI8LDw3E4HK4hsE6dOrF+/XrWrl1Lq1atsFqtzJw5kyZNmvDAAw8QExPjeiyTycTQoUMZPHgw2dnZREZGSibJY/g8Rszkrjy1+TxQfir1n3/+mT/84Q8MHTrUba/X2YyWyWh56ju3TyTNyMigsLAQOLMxORwOmjdvzv79+0lPT8dkMlFaWgrgmsizfft2fv75Z/z9/fnLX/7Co48+WmljgjP78tz5Rmm0TJLHs/MYMZO78thstjp7HofDgZ+fH0888YRbP8zq8rXTI5PR8oiK3NZ07Nu3j/HjxzN58mT27NkDlM80d150p127dkRGRvLuu++6NgyAH3/8kSuvvJJu3bqxevVqACwWS7XHz7vzPAFGyyR5PDsPGC+Tu/JkZGTU+fM4lzknstY1d7x27sxktDyianX+yiul2LRpEwsWLMDhcFBWVsa6deto2bIljRo1qnBc/U033cT777/Po48+SmJiIpmZmezbt4+HH36Y7OxsVqxYQV5enkdc38FImSSPZ+cxYiZ35THa62bETEbLI86vzr/OaJrGhg0byMnJ4Z577uH2229n3bp17Nixw9XBOo+lTklJ4cknn6Rly5Zs376dsLAwnn/+eXr06EFAQAA+Pj4esTEZLZPk8ew8YLxM7spjtNcNjJfJaHnE+WnKeWacOuC80NLRo0ddlwguKytj0qRJBAQEMGbMmAoXVDp7/11ZWZlr+OzkyZP85z//ITg4mMcee8y1IerBaJkkj2fnMWImd+Ux2utmxExGyyMurFb/KhkZGaxfv55ff/0VOLPfLCwsjLCwMOx2Oz4+PgwbNozdu3eTlpbmmgwEFa+P4OfnR1FREb/99hupqakcP36c66+/Hk3T3LoxGS2T5PHsPEbM5K48Bw8eNNTrBrIteHoecfFqZU5HcXExM2fOZNOmTTRu3Jjc3Fy6d+/ODTfcUOEUyWazGYBu3bpxxRVXsGzZMhISEqo8A1xWVhZLly4lPT2d7OxsRo4cSceOHWuj3HqZSfJ4dh4jZnJXnjZt2jB9+nTDvG4g24Kn5xGXQdWCxYsXq7/+9a9q586d6siRI+rHH39UjzzyiBozZozKzs5WSinlcDgq3OfgwYNq+PDhatasWSo/P7/Kx/3www/Vp59+qkpLS2ujzItitEySx7PzKGW8TO7KY7TXTSnjZTJaHnHpLmsMyuFwUFxczPr164mLi6Nt27ZERETQpUsXRo0ahdls5r///S9Q+TLD0dHR3HDDDXz77bekp6djs9nYs2cP2dnZrnVuu+02Bg8e7NbDm4yWSfJ4dh4jZnJXHpPJZKjXDWRb8PQ84vJddNNx9lX7TCYTAQEBnDp1iubNm1c4YUvnzp0ZMGAAu3bt4ptvvql0X4CBAwcSFBTEl19+ydy5c3nmmWeYPXu263bnUFtdM1omyePZec6tywiZ3JXH4XC48hjhdTu3LiNkMloeUbtq3B4WFxezZMkSTp48iZ+fHz179qRt27YUFxcTFRXFli1bGDRoEL6+vq43hi5dutC9e3c+++wz+vfvX+UV/xITE1m9ejU7duzg9ttvZ8CAAbWdsd5kkjyenceImdyV54YbbuDTTz81zOvmztfOaNuCO/9GovbVaKTjm2++4aGHHmLr1q0cPXqUNWvW8NJLL/HDDz8QEBBAixYt+O2339iyZUuF+zVp0oQ+ffpw8uRJVq1aBZzpZPfu3ctrr73G6tWrue6663j77bfdujEZLZPk8ew8RszkrjwhISGGet1AtgVPzyPqznlHOhwOB6tXr+arr77i1ltvpX///gQEBHDy5EleeukllixZQrdu3bjyyitZu3YtGzZsoEOHDgQEBGC32zGbzbRs2ZKIiAh2797NNddc4+pkMzMzcTgcvPjii1XOTK4rRsskeTw7jxEzuStPbGysoV43d752RtsW3Pk3EnXrvCMdmqaxadMmWrZsSf/+/QkJCcHPz4/w8HBSUlL49ddfOX78OK1atSIpKYnt27ezdu3aCo/RrFkzfHx8sNvtrpO6APTt25dnnnnG7RuT0TJJHs/OY8RM7spjtNcNZFvw9Dyi7p13pEPTNO655x6Cg4MJCAiocFtZWZlr9jjAkCFD2L9/P0uWLKFVq1auDSUvL4/CwkLCw8MB914cqypGyyR5PDsPGC+Tu/IY7XUD42UyWh5R9y7417VYLAQEBLi6T+fPwsJC/Pz8sFgsKKVo3LgxgwcPJigoiJdffpkvvviCrVu38umnn2K32+nRo0fdJrkIRsskeTw7Dxgvk7vyGO11A+NlMloeUbdqfPSKs/t0/ty9ezdt27bFz8/PtW+uW7duREZGMmvWLJYuXYqmaQQGBvLoo4/SokWLuklwGYyWSfJ4dh4wXiZ35THa6wbGy2S0PKKOXMoZxYqKitS9996rFi9eXGG53W5XSills9lUQUGBOnDgwKU8vC6MlknyeD6jZXJXHqO9bkoZL5PR8ojac0k7zzIzMzl16pRrn5zD4WDfvn189913lJaW4uvrS2BgIDExMbXaINUlo2WSPJ7PaJnclcdorxsYL5PR8ojac1FNh1IKgD179hAYGEhsbCx5eXnMnj2bJ598kl27drnW8RZGyyR5PJ/RMrkrj9FeNzBeJqPlEbXvok5Y7zw3/p49e4iNjWXVqlUsXryYgIAAJk6cSNeuXeukyLpktEySx/MZLZO78hjtdQPjZTJaHlH7LvoqOTabjf3795Odnc3evXsZMmQIt9xyS13U5jZGyyR5PJ/RMrkrj9FeNzBeJqPlEbXropsOPz8/WrduTbdu3bjjjjvw9fWti7rcymiZJI/nM1omd+Ux2usGxstktDyidmnqEnawORwOw53AxWiZJI/nM1omd+Ux2usGxstktDyi9lxS0yGEEEIIcbGkFRVCCCGEW0jTIYQQQgi3kKZDCCGEEG4hTYcQQggh3EKaDiGEEEK4xUWfp0MIIWrDjh07mDx5coVlZrMZf39/QkJCaNasGZ06daJv374EBQXV+vO98cYbWK3Wy35cIUTNSdMhhPAYdrudwsJCCgsLyc7O5scff2TevHk8+OCDXHnllXqXJ4S4TNJ0CCE8QnJyMnFxceTn5/Prr7+yY8cOAIqKivj3v/+N3W6nT58+OlcphLgc0nQIITxCly5d6Nu3r+v3nTt38tJLL1FUVATAW2+9RadOnQgJCSE7O5ulS5eyb98+8vLyyM/PRylFSEgIrVu35sYbbyQhIcH1WGPHjuXo0aMVnm/cuHGu/7/mmmsYO3as6/e9e/eydOlSdu3axYkTJ/D19SUmJoZ+/frRt29fOdumEJdImg4hhEdKSEjgjjvu4J133gGguLiYb775hgEDBpCRkcHXX39d6T7Hjh3j2LFjbNq0iQceeID+/ftf9PN++eWXzJkzp8Il2MvKyti9eze7d+8mLS2N8ePHYzabLz2cEPWUNB1CCI911VVX8e6777oagO3btzNgwADMZjNxcXHExcXRsGFDGjRoQGFhIdu3b2fv3r0opXj//ffp06cPfn5+DBw4kP3797NixQrXYw8cONA1QTUmJgYoH105u+Ho2LEj7du358SJE6xevZqSkhLS0tJYuHAhgwcPdvOrIYT3k6ZDCOGxAgMDCQkJ4eTJkwAcP34cgCuuuIIrrriCzMxMMjIyOH36NGazmaSkJPbu3QtAQUEBe/fuJSEhgZSUFHbs2FGh6bj22msrHb3y5ZdfuhqOXr168dhjj7lui42N5a233gJg6dKlDBo0SHazCHGRpOkQQni0qq5JmZ2dzWuvvUZ6evp57+tsUmpq9+7drv/fuHEjQ4cOrXK9/Px8srKyiIqKuqjHF6K+k6ZDCOGxCgoKOH36tOv3Jk2aAPCvf/2LgwcPXvD+ZWVlF/18NXV2XUKImpGmQwjhsdasWVNhpCMxMZHDhw9XaDhuvvlmBgwYQEhICCUlJYwcOfKSny8oKIhTp04B0LVrVzp06FDtuuHh4Zf8PELUV9J0CCE80vbt2/n4449dv/v7+9O/f3+OHDlSYb2rrrqKkJAQADZs2FDt4517tInNZqu0Tnx8PGlpaQCcOnWKG2+8EV9f3wrrnDp1il27dmGxWC4ukBBCmg4hhGfYunUrp06doqCggD179rhODuZ0//33ExISglIKTdNcIyDTp08nOTmZ3Nxc1q5dW+3jO3fNOL3zzjt07twZk8lEUlISkZGR3HzzzWzZsgWlFOnp6Tz++OMkJSURHBzMqVOn2LdvH3v27KFt27b06NGj9l8EIQxOmg4hhEf47rvv+O677yotDwwM5MEHH6RXr14ANGrUiP79+7Ny5UoAMjMzmTdvHgBXX301a9asqfLxrVYrLVu2ZP/+/UD5tVicjY3VaiUyMpKEhATuvPNO12GzR44cYcmSJbWeVYj6SpoOIYTHMJlM+Pv706hRI5o1a0bnzp3p27cvgYGBFda79957CQ0N5dtvv+XEiRNYLBauueYaBg0aVG3TATB+/HjmzJnDzp07KSgoqPLImD/+8Y+0b9+er7/+ml9++YXjx49jNptp0qQJzZo1o3v37lxxxRW1nl2I+kBTVf2rE0IIIYSoZXJmGyGEEEK4hTQdQgghhHALaTqEEEII4RbSdAghhBDCLaTpEEIIIYRbSNMhhBBCCLeQpkMIIYQQbiFNhxBCCCHcQpoOIYQQQriFNB1CCCGEcIv/B9QF3cFiS5QVAAAAAElFTkSuQmCC\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "df['Distance'].dropna().cumsum().plot.line(ylabel=\"km\");" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Some people have also made custom themes, like this fun [cyberpunk theme](https://github.com/dhaitz/mplcyberpunk):" ] }, { "cell_type": "code", "execution_count": 109, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import mplcyberpunk\n", "plt.style.use(\"cyberpunk\")\n", "\n", "df['Distance'].plot.line(ylabel=\"km\")\n", "mplcyberpunk.add_glow_effects()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "There are many other kinds of plots you can make too:\n", "\n", "|Method|Plot Type|\n", "|---|---|\n", "|`bar` or `barh` | bar plots|\n", "|`hist` | histogram|\n", "|`box` | boxplot|\n", "|`kde` or `density` | density plots|\n", "|`area` | area plots|\n", "|`scatter` | scatter plots|\n", "|`hexbin` | hexagonal bin plots|\n", "|`pie` | pie plots|" ] }, { "cell_type": "code", "execution_count": 110, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "plt.style.use('ggplot')\n", "plt.rcParams.update({'font.size': 16,\n", " 'axes.labelweight': 'bold',\n", " 'figure.figsize': (8,6)})\n", "df['Distance'].plot.hist();" ] }, { "cell_type": "code", "execution_count": 111, "metadata": {}, "outputs": [ { "data": { "image/png": "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eOqpp5g7dy7p6elOlxOUEhISuOuuuxg6dCjJycmAb7xMRUUFf/7znyMm8E+noaEBr9fL9OnT+c53vgP4ruEXFxezfPnyHge+TumL4Bss87//+7+88MILLQbMSEsjR45k/PjxfP/732fq1Km88sorTpcUFF588UXi4+P51re+RUNDAw0NDYDv56rp75EuNjaWSZMmNYd9k0mTJlFUVERtba1DlQWPPn36AL42OdnEiRMpKCjo8ZgZ9fAl4nm9Xn7729/y7rvvcu2113LDDTc4XVJQKSoq4tNPP+WSSy7BGNO8fdiwYWzdutXByoLHpk2bKCkp4bvf/W6L7StWrGDFihURPR+/yeHDh/nkk0+45JJLWgxorKurIyYmhtjYWAerCw6ZmZlA68GwHo8Ha22Lz193KPAl4i1dupR3332Xm266iauuusrpcoJOQUEBTz75JOnp6YwfPx7w9Vy3b98e8SOum/z7v/879fX1Lbbdf//9nH/++a1GXEeq8vJyfv/735OUlMTUqVMB38/Rhx9+yNixY3scZuFg7NixREdH8/7773PGGWc0b9+6dSsjR44kKiqqR8dX4EtE+/LLL/nLX/7CxIkTGT16NLt3725+zOVyMXLkSAerCw4TJkxg1KhRPPHEE1x//fX069ePv/71r+zatYu77rrL6fKCQltffFwuF8nJyYwYMcKBioLPuHHjOOOMM3j66ac5duwYycnJvPXWW+Tn5/PAAw84XV5QiI+P59prr2X58uXExcUxbtw4NmzYwGeffcadd97Z4+Mr8CWibd68ubm3un379haPxcbG8txzzzlUWfCIioriZz/7GS+88AJ/+tOfOHbsGMOHD+eee+5p7vGLdMTlcrF48WJeeOEF8vLyqKqqav450peir1133XXEx8fzxhtv8Nprr5GVlcWiRYtaXdfvDmNPtz6kiIiIhAWN0hcREYkACnwREZEIoMAXERGJAAp8ERGRCKDAFxERiQAKfBERkQigwBcREYkACnwREZEIoMAXERGJAP8/5UkXx2J4G28AAAAASUVORK5CYII=\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "df['Distance'].plot.density();" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Pandas Plotting" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Pandas also supports a few more advanced plotting functions in the `pandas.plotting` module. You can view them in the [Pandas documentation](https://pandas.pydata.org/pandas-docs/stable/user_guide/visualization.html#plotting-tools)." ] }, { "cell_type": "code", "execution_count": 112, "metadata": {}, "outputs": [], "source": [ "from pandas.plotting import scatter_matrix" ] }, { "cell_type": "code", "execution_count": 113, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "scatter_matrix(df);" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We have an outlier time in the data above, a time value of ~48,000. Let's remove it and re-plot." ] }, { "cell_type": "code", "execution_count": 114, "metadata": {}, "outputs": [ { "data": { "image/png": "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XiAmJkaTsviJy+XiwIED7N69m8zMTLvLEQG8v3iWlpaSmZlJZmYmGzZs4He/+x2JiYl+2X9xcTELFy7k448/5s9//rMCvoFRwAegsrIyysvLSU1NpV+/frz++ut2lxT0EhMTycvLIycnh/79+zN37ly7S5IG7E9/+hORkZFUVFSQl5fHsmXLWL9+PdnZ2bz00ks8++yzAPz617+mvLwcwzDq1c6CBQv45JNP/Fm6BBFdgw9AOTk5TJ48mZycHHbv3o3H47G7pKB37jE9cOCAjqnYKjY2loSEBJKSkkhNTeVXv/oV1113HQD79u1j586dAMTExBAfH09cXFy92tFNUg2bevABqLS0lNLSUu644w5ef/11Tpw4YXdJQU/HVALdkCFD2LZtG+B9TO61115b7TX4VatWsXz5cjIzMzlz5gyNGzemQ4cO3H333bRs2RL49vr9Wb/4xS9ITEzk1VdfBeDw4cN88MEHpKenc/r0acLDw0lOTmbQoEFVZnk8O3YgLi6OF198kXfffZctW7ZQUlJCu3btuPfee+nYsWOV75Kens7ChQtJT0/nzJkzxMXF0aNHD26//XZiYmJ82505c4aFCxeyfv16cnNzady4Md26deOuu+4iPj7e/we5gVEPPgANHTqUPXv2ADBmzBjNxe0HOqYS6Fq3bu17XdMz3ZcsWcJrr73Gvn37KCkpwePxcOrUKbZs2cKUKVPIysq6aFvHjx9nypQpbNy4kby8PCoqKigqKmLfvn28/vrrF3xOellZGVOmTGHFihWcPn2a8vJy9uzZw7Rp0ygsLPRtt3HjRqZMmcLnn39OYWEh5eXlZGdns2TJEp555hmKi4t9+/v973/Phx9+SHZ2NhUVFZw8eZKVK1fy29/+lpycnNofPLkgBXwA6tChA926dQPA7XYzfvx4mysKfjqmEugiIyN9r88NzO9auXIlAO3atWP69Om88sorTJgwgZCQEDweD5s3bwa81+8HDBjg+9wf//hH37X9tWvXUlxcjNvt5sknn+SVV17h17/+te9a/9atW89rt7CwkMrKSp5++mmee+452rVrB0BJSYmvzdLSUmbPnk1lZSVNmjThN7/5DS+99BIjRowA4MiRI3z66acALF26lH379gHw4x//mJdeeolJkybRtGlTTp48yTvvvFPnYyhV6RS9iEgAOHcgXWVlZbXbnX3e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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "scatter_matrix(df.query('Time < 4000'), alpha=1);" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 5. Pandas Profiling" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Pandas profiling is a nifty tool for generating summary reports and doing exploratory data analysis on dataframes. [Pandas profiling](https://github.com/pandas-profiling/pandas-profiling) is not part of base Pandas but you can install with: \n", "\n", "```\n", "$ conda install -c conda-forge pandas-profiling\n", "```" ] }, { "cell_type": "code", "execution_count": 115, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [] }, "execution_count": 115, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import pandas_profiling\n", "df = pd.read_csv('data/cycling_data.csv')\n", "df.profile_report(progress_bar=False)" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.8" }, "toc": { "base_numbering": 1, "nav_menu": {}, "number_sections": false, "sideBar": true, "skip_h1_title": true, "title_cell": "Lecture Outline", "title_sidebar": "Contents", "toc_cell": true, "toc_position": { "height": "calc(100% - 180px)", "left": "10px", "top": "150px", "width": "305.797px" }, "toc_section_display": true, "toc_window_display": true } }, "nbformat": 4, "nbformat_minor": 4 }