diff --git a/README.md b/README.md
index f8d0424..e49afab 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,8 @@
# JupyterLite Demo
-[![lite-badge](https://jupyterlite.rtfd.io/en/latest/_static/badge.svg)](https://jupyterlite.github.io/demo)
+[![lite-badge](https://jupyterlite.rtfd.io/en/latest/_static/badge.svg)](https://humbledata.org/online-workshop/lab/index.html)
+
+> This repository holds the contents for the HumbelData workshop using JupyterLite.
JupyterLite deployed as a static site to GitHub Pages, for demo purposes.
diff --git a/content/notebooks/1. Beginning with Python.ipynb b/content/notebooks/1. Beginning with Python.ipynb
index f393375..5d56c1e 100644
--- a/content/notebooks/1. Beginning with Python.ipynb
+++ b/content/notebooks/1. Beginning with Python.ipynb
@@ -1,8 +1,28 @@
{
+ "metadata": {
+ "kernelspec": {
+ "name": "python3",
+ "language": "python",
+ "display_name": "Python 3 (ipykernel)"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "python",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.8"
+ }
+ },
+ "nbformat_minor": 4,
+ "nbformat": 4,
"cells": [
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"
\n",
"
\n",
@@ -11,11 +31,11 @@
"Introduction to Python\n",
"\n",
"
"
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"## Welcome to learning Python!\n",
"\n",
@@ -24,108 +44,139 @@
"We will walk you through different aspects of the Python language interactively. Take your time to experiment with it if you like and don't hesitate to ask or Google things. One of the first lessons in programming is using the documentation and information shared by other programmers. Jupyter has another trick, where you can put your cursor into the brackets of a function call such as `print()` and hit **Shift + Tab**. This will let you see the documentation of a function directly in the notebook (*pro-tip*: you can hit it up to four times for different effects).\n",
"\n",
"As for Python itself, one of the big strengths of Python is the extensibility. It has a surprising amount of functionality directly within the core language, however, you can `import` almost arbitrary code others make available as libraries. Below you can see a special import that shows you the \"Zen of Python\" a set of guidelines that could guide your programming journey.\""
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# We can use comments to document our code in a coding cell.\n",
+ "import this # Zen of Python"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# We can use comments to document our code in a coding cell.\n",
- "import this # Zen of Python"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"**--> Simple is better than complex.** \n",
"It is really easy to print ***Hello World*** in Python:"
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "print('Hello World!')"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "print('Hello World!')"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"**PEP 8** is Python's style guide. You can find it here:\n",
"https://www.python.org/dev/peps/pep-0008/\n",
"\n",
"It is good to know about, but when you become a professional programmer there are programs called a \"linter\" that will help you adhere to PEP 8."
- ]
+ ],
+ "metadata": {}
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "Before you get started, we just need to do a small amount of set up. We're going to load a module called NumPy which we'll need to complete this notebook. Don't stress if you don't understand this code - it's specific to the JupyterLite notebooks we're using for this course."
+ ],
+ "metadata": {}
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "outputs": [],
+ "source": [
+ "import pyodide_js\n",
+ "\n",
+ "# Install NumPy\n",
+ "await pyodide_js.loadPackage('numpy')"
+ ],
+ "metadata": {
+ "collapsed": false
+ }
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"
\n",
"Variables\n",
"
\n",
"
"
- ]
+ ],
+ "metadata": {
+ "collapsed": false
+ }
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"In programming it's very useful to store values. Accessing values through names is called a variable. Python is very user-friendly in that it will let you store most things in a variable, without making space in the computer's space explicitly. Moreover, computers need to differentiate between the type of data, such as, `5` being an integer and `'Hello'` being a string, but Python attempts to handle these intuitively for you. You will learn about the different types in the following sections!\n",
"\n",
"**Python is an object oriented programming language. You do not need to declare variables (or their types) before using them as every variable in Python is an object.** "
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "name = 'Sandrine'"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "name = 'Sandrine'"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "print(name)"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "print(name)"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"Moreover, variables can easily be updated. Try it out below!"
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"---\n",
"\n",
@@ -139,200 +190,219 @@
"\n",
"\n",
"---"
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
">Assign another string to the variable 'name' and print this variable"
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false
},
- "outputs": [],
- "source": []
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/01_01.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/01_01.py"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"**!!! Variable can can change type when re-assigned.**"
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
">Assign a number (without quotes) to the variable 'name' and print this variable"
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false
},
- "outputs": [],
- "source": []
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/01_02.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/01_02.py"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"---"
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"
\n",
"Strings\n",
"
\n",
"
"
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"A string always begins and ends with a single ( ' ) or double ( \\\" ) quotes. There is no difference, except if there is an apostrophe ( ' ) inside the string."
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "'Beginners Data Workshop'"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "'Beginners Data Workshop'"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "\"Beginner's Data Workshop\""
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "\"Beginner's Data Workshop\""
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
">Write *I'm enjoying this workshop!* using double quotes, and then single quotes."
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# double quotes\n"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# double quotes\n"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false
},
- "outputs": [],
- "source": []
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/01_03.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/01_03.py"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# single quotes\n"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# single quotes\n"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/01_04.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/01_04.py"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"**Oh no, an error!** Errors are nothing to be afraid of. Think of them as friendly messages trying to help you understand what's gone wrong. Here's how to read this:\n",
"- Read errors backwards, so start at the bottom! It's a \"SyntaxError\" which means there's something wrong with our Python code.\n",
@@ -342,294 +412,321 @@
"**It turns out, if you want to use single quotes inside single quotes, you need to \"escape\" the quote with a backslash ( \\\\ ).**\n",
"\n",
">Let's try that!"
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# single quotes, second try\n"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# single quotes, second try\n"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/01_05.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/01_05.py"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"As mentioned before, Python tries to handle everything as intuitively as possible. That means strings can be added together."
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "'We are ' + 'everywhere around the world.'"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "'We are ' + 'everywhere around the world.'"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"Also, strings can even be multiplied by a number."
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "'Great! 🎉' * 3"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "'Great! 🎉' * 3"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "'😂' * 50"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "'😂' * 50"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"We can access parts of strings by slicing the string. A character of a string (which is considered as a string of length 1 by Python) using slice, and a substring using slice range. Something important to note:\n",
"\n",
"**!!! Like birthdays, Python starts counting from 0! (It is \"zero-indexed\")** \n",
"\n",
"(If you're interested why, here's a historical [letter from Dijkstra](https://www.cs.utexas.edu/users/EWD/transcriptions/EWD08xx/EWD831.html) about it.)"
- ]
+ ],
+ "metadata": {}
},
{
+ "cell_type": "markdown",
+ "source": [
+ "![image.png](attachment:image.png)"
+ ],
+ "metadata": {},
"attachments": {
"image.png": {
"image/png": "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"
}
- },
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "![image.png](attachment:image.png)"
- ]
+ }
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "s = 'I am a Pythonista.'"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "s = 'I am a Pythonista.'"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"***Slice*** \n",
"We can access characters of a string by referencing the position (\"index\") numbers within square brackets."
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# Selecting the first character of the string s\n",
+ "s[0]"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# Selecting the first character of the string s\n",
- "s[0]"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"> Select the last character of the string s"
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false
},
- "outputs": [],
- "source": []
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/01_06.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/01_06.py"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"***Slice range*** \n",
"We can get a range of characters of a string by using a slicing range."
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# Select from position 2 up to but not including position 6 of the string s\n",
+ "s[2:6] # 6 is excluded"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# Select from position 2 up to but not including position 6 of the string s\n",
- "s[2:6] # 6 is excluded"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"We can skip the start (resp. stop) number `s[:6]`. Then it start form index 0 (resp. end at the highest index)."
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
">Select the last 3 characters of the string s"
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false
},
- "outputs": [],
- "source": []
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/01_07.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/01_07.py"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"We can check if a string contains another string inside of it (a \"substring\"), using *in* and *not in*.\n",
"\n",
"**!!! Python is case-sensitive! The string `'a'` is not equal to `'A'`***"
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
- "metadata": {
- "jupyter": {
- "outputs_hidden": false
- }
- },
- "outputs": [],
"source": [
"# Checking if s contains 'python'\n",
"print(s)\n",
"'python' in s"
- ]
+ ],
+ "metadata": {
+ "jupyter": {
+ "outputs_hidden": false
+ },
+ "collapsed": false,
+ "trusted": true
+ },
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"> Check if s does not contain 'I' (capital i)"
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false
},
- "outputs": [],
- "source": []
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/01_08.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/01_08.py"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"---\n",
"\n",
@@ -637,409 +734,442 @@
"Numbers\n",
" \n",
""
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"Python has different numerical types. Two of which are used more often than others:\n",
"- **Integers:** These are whole numbers, i.e. `1`, `2`, `-5`\n",
"- **Floats:** \"Floating point\" numbers are those with a decimal point, i.e. `3.14158`, `2.5`, `0.1` and even `3.0`. \n",
"\n",
"Python attempts to deal with these numbers intuitively when integers and floats are mixed."
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"### Basic Operators"
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"**Addition:** \n",
- ">Try adding two numbers."
- ]
+ ">Try adding 3 and 4 together."
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false
},
- "outputs": [],
- "source": []
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/01_09.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/01_09.py"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"**Subtraction:**\n",
- "> Try subtracting two numbers."
- ]
+ "> Try subtracting 6 from 10.0."
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false
},
- "outputs": [],
- "source": []
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/01_10.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/01_10.py"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"**Multiplication:** \n",
"The sign for multiplication is *. \n",
- ">Try multiplying two numbers."
- ]
+ ">Try multiplying 15 and 12."
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false
},
- "outputs": [],
- "source": []
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/01_11.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/01_11.py"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"**Exponent:** \n",
"The sign for exponent (or power) is *`**`*.\n",
"\n",
- "> Try the power of an integer."
- ]
+ "> Try raising 2 to the power of 6."
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false
},
- "outputs": [],
- "source": []
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/01_12.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/01_12.py"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
- ">Try the power of a float"
- ]
+ ">Try raising a float to a power this time. Calculate the square of 3.1."
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false
},
- "outputs": [],
- "source": []
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/01_13.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/01_13.py"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
- ">Try the power of an integer written as a float (e.g. 12.0)"
- ]
+ ">Now try something similar - raise an integer written as a float to a power. Calculate the square of 5, where 5 is written as a float."
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false
},
- "outputs": [],
- "source": []
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/01_14.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/01_14.py"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"**Division and modulo**\n",
"- The sign for division is **`/`**.\n",
"- The sign for floor division is **`//`**. It returns the \"quotient\" of a division - how many times one number goes into another. (\"If six people can sit around a dinner table, and we have 99 guests coming, how many tables do we need?\")\n",
"- The **`%`** sign is the [modulo](https://en.wikipedia.org/wiki/Modulo_operation), which returns the \"remainder\" after division."
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
- ">Divide 6 by 2"
- ]
+ ">Divide 6 by 2."
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false
},
- "outputs": [],
- "source": []
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/01_15.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/01_15.py"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
- ">Try the floor division of 6 by 2"
- ]
+ ">Try the floor division of 6 by 2."
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false
},
- "outputs": [],
- "source": []
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/01_16.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/01_16.py"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
- ">Divide 19 by 5"
- ]
+ ">Divide 19 by 5."
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false
},
- "outputs": [],
- "source": []
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/01_17.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/01_17.py"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"*Note*: division returns a float."
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"**The floor division returns an int, the non-fractional part.** \n",
- ">Try the floor division of 19 by 5"
- ]
+ ">Try the floor division of 19 by 5."
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false
},
- "outputs": [],
- "source": []
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/01_18.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/01_18.py"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"**Modulo returns the remainder of the division**"
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
- ">Calculate 19 modulo 5"
- ]
+ ">Calculate 19 modulo 5."
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false
},
- "outputs": [],
- "source": []
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/01_19.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/01_19.py"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"**--> 19 = 3 * 5 + 4**"
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"---\n",
"\n",
@@ -1047,44 +1177,48 @@
"Order of operations\n",
" \n",
""
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"The order of operations in Python respects the usual rules of mathematics (brackets -> powers -> division/multiplication -> add/subtract). **If in doubt, use brackets** to make it clear (to yourself, and anyone who might be reading your code) what you're trying to do."
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "5 + 6 * 10"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "5 + 6 * 10"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "(5 + 6) * 10"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "(5 + 6) * 10"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"---\n",
"\n",
@@ -1092,110 +1226,119 @@
"Booleans\n",
" \n",
""
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"Booleans are the two constant values `True` and `False`. Python implements the concept of \"truthiness\", that means their numerical values are 1 and 0. These values are especially important for comparisons, therefore, we'll also learn about a new operator:\n",
"\n",
"**`==`** is an equality operator, different from **`=`** which is the assignment operator you used to assign variables."
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "True == 1 # '==' is an equality operator, different from '=' which is an assignment operator"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "True == 1 # '==' is an equality operator, different from '=' which is an assignment operator"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "False * 3"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "False * 3"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
">Using **`!=`** , check if False is not equal to 2.\""
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false
},
- "outputs": [],
- "source": []
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/01_20.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/01_20.py"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
">Check if the length of your name is greater than 8."
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "len()"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/01_21.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/01_21.py"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"We can use `and` and `or` operators with booleans in Python. Type them below and see how the color of the text changes, because Python recognises the keyword! These can be used to chain together multiple comparisons. These follow mathematical logic.\n",
"\n",
@@ -1207,35 +1350,38 @@
"| False | False | False | False |\n",
"\n",
"> Check if the length of your name is greater than 5 and the length of your mentor's name is less than 7."
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false
},
- "outputs": [],
- "source": []
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/01_22.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/01_22.py"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"---\n",
"\n",
@@ -1243,397 +1389,433 @@
"Lists\n",
" \n",
""
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"A list is a list of comma-separated values between square brackets.\n",
"\n",
"The items of a list can have different types."
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "list_greeting = ['Hallo', 'Bonjour', 10, 'Hello', 'Ciao', False]"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "list_greeting = ['Hallo', 'Bonjour', 10, 'Hello', 'Ciao', False]"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"We can access a single value using a slice, and several values using slice range. Check the \"string slicing\" section above for this."
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
">Get the first item of the list."
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false
},
- "outputs": [],
- "source": []
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/01_23.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/01_23.py"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"Get every the items from the list, starting with the 4th one.\n",
"\n",
"Note that there is no need to put a number after the colon when when want to select until the end of the list."
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
">Get the items starting with the one with index 3 until the end of the list."
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false
},
- "outputs": [],
- "source": []
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/01_24.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/01_24.py"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"**Get the items from the list until the 4th one.**"
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
">Get the items from the beginning of the list until the value with index 4 (index 4 is excluded)."
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false
},
- "outputs": [],
- "source": []
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/01_25.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/01_25.py"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"**Advanced slicing allows us to set how the list's index will increment between the start/stop indexes we select.** \n",
"The slicing then looks like this: [start:stop:step] \n",
"For example, if we want to select every third items of a list, we will set the step as 3."
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
">Get every other items from the list of greetings"
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false
},
- "outputs": [],
- "source": []
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/01_26.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/01_26.py"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"**We can update a list by re-assigning a value selected using a slice.** \n",
"For example, we can replace False with 'Ave' in list_greeting."
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "list_greeting[-1] = 'Ave'\n",
+ "print(list_greeting)"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "list_greeting[-1] = 'Ave'\n",
- "print(list_greeting)"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
">Replace 10 with Hola in list_greetings, then print list_greeting to check it."
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": []
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/01_27.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/01_27.py"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"We can have lists inside a list, these are often called \"nested lists\":"
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "list_of_lists = [[1, 2, 3], [4, 5]]"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "list_of_lists = [[1, 2, 3], [4, 5]]"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "list_of_lists[0] # access the first element of the list, which is a list."
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "list_of_lists[0] # access the first element of the list, which is a list."
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "list_of_lists[0][-1] # access the last element of the first list."
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "list_of_lists[0][-1] # access the last element of the first list."
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"We can concatenate lists using ' + '."
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "[1, 2, 3] + [4, 5, 6]"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "[1, 2, 3] + [4, 5, 6]"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"We can also use the multiplication to repeat values in a list (only works with integers)."
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "['Hey'] * 5"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "['Hey'] * 5"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"We can also use `in` / `not in` with lists."
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
">Check if `10` is in `list_greeting`."
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false
},
- "outputs": [],
- "source": []
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/01_28.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/01_28.py"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
">Check if 'Ole' is not in list_greeting."
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false
},
- "outputs": [],
- "source": []
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/01_29.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/01_29.py"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"---\n",
"\n",
@@ -1641,216 +1823,236 @@
"Built-in functions\n",
" \n",
""
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"You've seen your first function at the very beginning of this notebook, i.e. `print(\"Hello World\")`. Functions are a way for you to write reusable code. In the case before `print()` is Python's way for you to show an output you provide. However, there are many other useful functions that Python comes with, that are provided by other libraries, or written by you yourself to save you from repeating some code.\n",
"\n",
"The functions that are always available in Python can be found here:\n",
"https://docs.python.org/3/library/functions.html"
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
">Print *'Here we are!'*."
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false
},
- "outputs": [],
- "source": []
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/01_30.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/01_30.py"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
">Compute the length of the string variable `snakes`."
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
"source": [
"snakes = \"🐍🐍🐍🐍🐍🐍🐍🐍🐍🐍🐍🐍🐍🐍🐍🐍🐍🐍🐍🐍🐍🐍🐍🐍🐍🐍🐍🐍🐍🐍🐍🐍🐍🐍🐍🐍🐍🐍🐍🐍🐍🐍\""
- ]
+ ],
+ "metadata": {
+ "trusted": true
+ },
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false
},
- "outputs": [],
- "source": []
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/01_31.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/01_31.py"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
">Compute the length of list_greeting."
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false
},
- "outputs": [],
- "source": []
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/01_32.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/01_32.py"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
">Work out the maximum of 1, 2, 3, 4 and 5."
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false
},
- "outputs": [],
- "source": []
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/01_33.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/01_33.py"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
">Round the number 123.45 to the nearest integer."
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false
},
- "outputs": [],
- "source": []
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/01_34.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/01_34.py"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
">Round the number 123.45 to 1 decimal place."
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false
},
- "outputs": [],
- "source": []
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/01_35.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/01_35.py"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"---\n",
"\n",
@@ -1858,64 +2060,69 @@
"Methods\n",
" \n",
""
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"A method is a function associated to an object. Basically, it provides a way for an object to know functions about themselves.\n",
"\n",
"For example, we can change the string `s` to upper case using the `.upper()` method."
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "s.upper()"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "s.upper()"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
">Using the append method, add 'Aloha' to list_greeting."
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false
},
- "outputs": [],
- "source": []
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/01_36.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/01_36.py"
- ]
+ "execution_count": 3,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"---\n",
"\n",
@@ -1923,20 +2130,20 @@
"Importing modules\n",
" \n",
""
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"We can import modules (Python code that can define functions, classes and variables).\n",
"\n",
"Usually, we write all the imports at the beginning of a Python program or notebook."
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"**A small warning** \n",
"Ensure you trust the packages you're installing!\n",
@@ -1946,77 +2153,84 @@
"2. Do I trust giving their code access to my computer?\n",
"3. `pip install` especially can be a little more dangerous, anyone can upload something to the Python Package Index (\"PyPI\" for short), which is where `pip` installs from. So be very careful especially as the smallest typo can be a security risk!\n",
"4. `conda install` is more of a walled garden and as such better positioned for enterprise usage."
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"> From the **math** library, import **sqrt** to work out the square root of **24 336**."
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false
},
- "outputs": [],
- "source": []
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/01_37.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/01_37.py"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"Python programmers really are lazy! (Or obsessive about productivity, take your pick!)\n",
"\n",
"Hence, you can define aliases for imports. The `as np` is two characters long, whereas `numpy` is five. It's less to type, when you write long programs.\n",
"\n",
"> Import `numpy as np` and try **`np.sin(np.pi/4)`**."
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": []
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/01_38.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/01_38.py"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"---\n",
"\n",
@@ -2024,28 +2238,8 @@
"Take a well deserved break, brew a relaxing beverage of your choice or go have a snack, maybe share a picture of your snack/drink in the #random channel, we love to see pictures from everyone attending around the world. ☕️\n",
"\n",
"![](https://media0.giphy.com/media/3otPoS81loriI9sO8o/200.gif)"
- ]
+ ],
+ "metadata": {}
}
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python (beginners-data-workshop)",
- "language": "python",
- "name": "beginners-data-workshop"
- },
- "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.9.13"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 4
+ ]
}
diff --git a/content/notebooks/2. First steps with Pandas.ipynb b/content/notebooks/2. First steps with Pandas.ipynb
index 85395c0..eb52b7c 100644
--- a/content/notebooks/2. First steps with Pandas.ipynb
+++ b/content/notebooks/2. First steps with Pandas.ipynb
@@ -1,8 +1,28 @@
{
+ "metadata": {
+ "kernelspec": {
+ "name": "python",
+ "display_name": "Python (Pyodide)",
+ "language": "python"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "python",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.8"
+ }
+ },
+ "nbformat_minor": 4,
+ "nbformat": 4,
"cells": [
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"
"
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"> ***Note***: This notebook contains solution cells with ***a*** solution. Remember there is not only one solution to a problem! \n",
"> \n",
"> You will recognise these cells as they start with **# %**. \n",
"> \n",
"> If you would like to see the solution, you will have to remove the **#** (which can be done by using **Ctrl** and **?**) and run the cell. If you want to run the solution code, you will have to run the cell again."
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"
\n",
"Data analysis packages\n",
"
\n",
"
"
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"Data Scientists use a wide variety of libraries in Python that make working with data significantly easier. Those libraries primarily consist of:\n",
"\n",
@@ -55,12 +75,31 @@
"\n",
"Though there are countless others available.\n",
"\n",
- "For today, we'll primarily focus ourselves around the library that is 99% of our work: `pandas`. Pandas is built on top of the speed and power of NumPy."
- ]
+ "For today, we'll primarily focus ourselves around the library that is 99% of our work: `pandas`. Pandas is built on top of the speed and power of NumPy.\n",
+ "\n",
+ "Run the code below to get the imports we need for this notebook."
+ ],
+ "metadata": {}
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "import pyodide_js\n",
+ "\n",
+ "# Install NumPy\n",
+ "await pyodide_js.loadPackage('numpy')\n",
+ "\n",
+ "# Install Pandas\n",
+ "await pyodide_js.loadPackage('pandas')"
+ ],
+ "metadata": {
+ "trusted": true
+ },
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"---\n",
"\n",
@@ -68,55 +107,48 @@
"Imports\n",
" \n",
""
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "import pandas as pd"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "import pandas as pd"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
">Import numpy using the convention seen at the end of the first notebook."
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/02_01.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": []
- },
- {
- "cell_type": "code",
"execution_count": null,
- "metadata": {
- "jupyter": {
- "outputs_hidden": false
- }
- },
- "outputs": [],
- "source": [
- "# %load ../solutions/02_01.py"
- ]
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"---\n",
"\n",
@@ -124,121 +156,132 @@
"Loading the data\n",
" \n",
""
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"To see a method's documentation, you can use the help function. In Jupyter, you can also just put a question mark before the method."
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "?pd.read_csv"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
},
- "scrolled": true
+ "scrolled": true,
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "?pd.read_csv"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"To load the dataframe we are using in this notebook, we will provide the path to the file: ../data/Penguins/penguins.csv"
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
- ">Load the dataframe, read it into a pandas DataFrame and assign it to df"
- ]
+ ">Load the dataframe, read it into a pandas DataFrame and assign it to df."
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": []
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/02_02.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/02_02.py"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"**To have a look at the first 5 rows of df, we can use the *head* method.**"
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "df.head()"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "df.head()"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
">Have a look at the last 3 rows of df using the tail method"
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false
},
- "outputs": [],
- "source": []
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/02_03.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/02_03.py"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"---\n",
"\n",
@@ -246,112 +289,121 @@
"General information about the dataset\n",
" \n",
""
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"**To get the size of the datasets, we can use the *shape* attribute.** \n",
"The first number is the number of row, the second one the number of columns"
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
- ">Show the shape of df (do not put brackets at the end)"
- ]
+ ">Show the shape of df (do not put brackets at the end)."
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false
},
- "outputs": [],
- "source": []
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/02_04.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/02_04.py"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
">Get the names of the columns and info about them (number of non null and type) using the info method."
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false
},
- "outputs": [],
- "source": []
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/02_05.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/02_05.py"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
">Get the columns of the dataframe using the columns attribute."
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false
},
- "outputs": [],
- "source": []
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/02_06.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/02_06.py"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"---\n",
"\n",
@@ -359,62 +411,55 @@
"Display settings\n",
" \n",
""
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"We can check the display option of the notebook."
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "pd.set_option('display.max_rows', [number of rows])"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "pd.options.display.max_rows"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
- ">Force pandas to display 25 rows by changing the value of the above."
- ]
+ ">Force pandas to display 25 rows by changing the value of [number of rows] above."
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/02_07.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": []
- },
- {
- "cell_type": "code",
"execution_count": null,
- "metadata": {
- "jupyter": {
- "outputs_hidden": false
- }
- },
- "outputs": [],
- "source": [
- "# %load ../solutions/02_07.py"
- ]
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"---\n",
"\n",
@@ -422,270 +467,302 @@
"Subsetting data\n",
" \n",
""
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"We can subset a dataframe by label, by index or a combination of both. \n",
"There are different ways to do it, using .loc, .iloc and also []. \n",
"See [documentation ](https://pandas.pydata.org/pandas-docs/stable/indexing.html)."
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
">Display the 'bill_length_mm' column"
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": []
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/02_08.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/02_08.py"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"*Note:* We could also use `df.bill_length_mm`, but it's not the greatest idea because it could be mixed with methods and does not work for columns with spaces."
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
">Have a look at the 12th observation:"
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# using .iloc (uses positions, \"i\" stands for integer)\n"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# using .iloc (uses positions, \"i\" stands for integer)\n"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/02_09.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/02_09.py"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# using .loc (uses indexes and labels)\n"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# using .loc (uses indexes and labels)\n"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/02_10.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/02_10.py"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
">Display the **bill_length_mm** of the last three observations."
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# using .iloc\n"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# using .iloc\n"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/02_11.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/02_11.py"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# using .loc\n"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# using .loc\n"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/02_12.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
},
- "scrolled": true
+ "scrolled": true,
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/02_12.py"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"And finally look at the **flipper_length_mm** and **body_mass_g** of the 146th, the 8th and the 1rst observations:"
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# using .iloc\n"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# using .iloc\n"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/02_13.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/02_13.py"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# using .loc\n"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# using .loc\n"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/02_14.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/02_14.py"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"**!!WARNING!!** Unlike Python and ``.iloc``, the end value in a range specified by ``.loc`` **includes** the last index specified. "
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "df.iloc[5:10]"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
},
- "scrolled": true
+ "scrolled": true,
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "df.iloc[5:10]"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "df.loc[5:10]"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "df.loc[5:10]"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"---\n",
"\n",
@@ -693,85 +770,92 @@
"Filtering data on conditions\n",
" \n",
""
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"**We can also use condition(s) to filter.** \n",
"We want to display the rows of df where **body_mass_g** is greater than 4000. We will start by creating a mask with this condition."
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "mask_PW = df['body_mass_g'] > 4000\n",
+ "mask_PW"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
},
- "scrolled": true
+ "scrolled": true,
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "mask_PW = df['body_mass_g'] > 4000\n",
- "mask_PW"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"Note that this return booleans. If we pass this mask to our dataframe, it will display only the rows where the mask is True."
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "df[mask_PW]"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "df[mask_PW]"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
">Display the rows of df where **body_mass_g** is greater than 4000 and **flipper_length_mm** is less than 185."
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false
},
- "outputs": [],
- "source": []
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/02_15.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/02_15.py"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"---\n",
"\n",
@@ -779,65 +863,70 @@
"Values\n",
" \n",
""
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"We can get the number of unique values from a certain column by using the `nunique` method.\n",
"\n",
"For example, we can get the number of unique values from the species column:"
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "df['species'].nunique()"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "df['species'].nunique()"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"We can also get the list of unique values from a certain column by using the `unique` method.\n",
">Return the list of unique values from the species column"
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false
},
- "outputs": [],
- "source": []
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/02_16.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/02_16.py"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"---\n",
"\n",
@@ -845,341 +934,373 @@
"Null Values and NaN\n",
" \n",
""
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"When you work with data, you will quickly learn that data is never \"clean\". These values are usually referred to as null value. In computation it is best practice to define a \"special number\" that is \"**N**ot **a** **N**umber\" also called NaN.\n",
"\n",
"We can use the `isnull` method to know if a value is null or not. It returns boolean values."
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "df['flipper_length_mm'].isnull()"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "df['flipper_length_mm'].isnull()"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"**We can apply different methods one after the other.**. \n",
"For example, we could apply to method `sum` after the method `isnull` to know the number of null observations in the **flipper_length_mm** column.\n",
">Get the total number of null values for **flipper_length_mm**."
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [],
"metadata": {},
- "outputs": [],
- "source": []
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
"source": [
- "# %load ../solutions/02_17.py"
- ]
+ "# %run ../solutions/02_17.py"
+ ],
+ "metadata": {
+ "trusted": true
+ },
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"To get the count of the different values of a column, we can use the `value_counts` method.\n",
"\n",
"For example, for the species column:"
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "df['species'].value_counts()"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "df['species'].value_counts()"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"If we want to know the count of NaN values, we have to pass the value `False` to the parameter **dropna** (set to `True` by default).\n",
"> Return the proportion for each sex, including the NaN values.\""
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false
},
- "outputs": [],
- "source": []
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/02_18.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/02_18.py"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"To get the proportion instead of the count of these values, we have to pass the value `True` to the parameter **normalize**.\n",
">Return the proportion for each species."
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false
},
- "outputs": [],
- "source": []
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/02_19.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/02_19.py"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
">Using the index attribute, get the indexes of the observation without **flipper_length_mm**"
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false
},
- "outputs": [],
- "source": []
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/02_20.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/02_20.py"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"Use the **[dropna](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.dropna.html)** method to remove the row which only has NaN values.\n",
">Get the help for the dropna method."
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": []
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/02_21.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
},
- "scrolled": true
+ "scrolled": true,
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/02_21.py"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
">Use the dropna method to remove the row of `df` where all of the values are NaN, and assign it to `df_2`."
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false
},
- "outputs": [],
- "source": []
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/02_22.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/02_22.py"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"We can use a f-string to format a string. We have to write a `f` before the quotation mark, and write what you want to format between curly brackets."
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "print(f'shape of df: {df.shape}')"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "print(f'shape of df: {df.shape}')"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"> Print the number of rows of `df_2` using a f_string. Did we lose any rows between `df` and `df_2`? If not, why not?"
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false
},
- "outputs": [],
- "source": []
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/02_23.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/02_23.py"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
">Use the dropna method to remove the rows of `df_2` which contains any NaN values, and assign it to `df_3`"
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/02_24.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/02_24.py"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
">Print the number of rows of `df_3` using a f_string."
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false
},
- "outputs": [],
- "source": []
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/02_25.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/02_25.py"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"---\n",
"\n",
@@ -1187,64 +1308,69 @@
"Duplicates\n",
" \n",
""
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
">Remove the duplicates rows from `df_3`, and assign the new dataframe to `df_4`"
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false
},
- "outputs": [],
- "source": []
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/02_26.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
},
- "scrolled": true
+ "scrolled": true,
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/02_26.py"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# checking the shape of df_4\n",
+ "df_4.shape"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# checking the shape of df_4\n",
- "df_4.shape"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"You should see that 4 rows have been dropped. "
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"---\n",
"\n",
@@ -1252,185 +1378,208 @@
"Some stats\n",
" \n",
""
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
">Use the describe method to see how the data is distributed (numerical features only!)"
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false
},
- "outputs": [],
- "source": []
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/02_27.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/02_27.py"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"We can also change the **species** column to save memory space. Note: You may receive a **SettingWithCopyWarning** - you can safely ignore this error for this notebook."
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "df_4['species'] = df_4['species'].astype('category')"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "df_4['species'] = df_4['species'].astype('category')"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
">Using the dtypes attribute, check the types of the columns of `df_4`"
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false
},
- "outputs": [],
- "source": []
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/02_28.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/02_28.py"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"We can also use the functions count(), mean(), sum(), median(), std(), min() and max() separately if we are only interested in one of those."
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
- ">Get the minimum for each numerical column of `df_4`"
- ]
+ ">Get the minimum for each numerical column of `df_4`. Make sure to include the argument `numeric_only=True` in the function to filter results to only numeric columns."
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false
},
- "outputs": [],
- "source": []
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/02_29.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/02_29.py"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
- ">Calculate the maximum of the **flipper_length_mm**"
- ]
+ ">Calculate the maximum of the **flipper_length_mm**."
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false
},
- "outputs": [],
- "source": []
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/02_30.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/02_30.py"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"We can also get information for each species using the `groupby` method.\n",
"\n",
"\n",
- "> Get the median for each **species**."
- ]
+ "> Get the median for each **species**. Again, make sure to include the argument `numeric_only=True` in the function to filter results to only numeric columns."
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
+ "source": [],
+ "metadata": {},
"execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "# %run ../solutions/02_31.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "# %load ../solutions/02_31.py"
- ]
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"---\n",
"\n",
@@ -1438,59 +1587,42 @@
"Saving the dataframe as a csv file\n",
" \n",
""
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
">Save df_4 using this path: `'../data/Penguins/my_penguins.csv'`"
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false
},
- "outputs": [],
- "source": []
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "# %run ../solutions/02_32.py"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
- },
- "outputs": [],
- "source": [
- "# %load ../solutions/02_32.py"
- ]
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3 (system-wide)",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
+ },
+ "collapsed": false,
+ "trusted": true
},
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.8.5"
+ "execution_count": null,
+ "outputs": []
}
- },
- "nbformat": 4,
- "nbformat_minor": 4
+ ]
}
diff --git a/content/notebooks/3.1 Visualization with Matplotlib.ipynb b/content/notebooks/3.1 Visualization with Matplotlib.ipynb
index 5385877..567fb7f 100644
--- a/content/notebooks/3.1 Visualization with Matplotlib.ipynb
+++ b/content/notebooks/3.1 Visualization with Matplotlib.ipynb
@@ -1,8 +1,28 @@
{
+ "metadata": {
+ "kernelspec": {
+ "name": "python",
+ "display_name": "Python (Pyodide)",
+ "language": "python"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "python",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.8"
+ }
+ },
+ "nbformat_minor": 4,
+ "nbformat": 4,
"cells": [
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"
",
+ "image/png": "iVBORw0KGgoAAAANSUhEUgAAAz8AAALjCAYAAAA83rujAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8qNh9FAAAACXBIWXMAAA9hAAAPYQGoP6dpAACNPUlEQVR4nOzde1wVdf7H8fcB5EAgB1HhSKLiJcULWmpIWnlhBUrTZGstt9QsywULbdeizUqzSLtommm6LmrlWlZa2aaZCd3UjKJ7hq7mFSgNEFYQZX5/uMyvo6CiHBDn9Xw85iEz852Zzxw5Z3ifmfmOzTAMQwAAAABwgfOo6wIAAAAAoDYQfgAAAABYAuEHAAAAgCUQfgAAAABYAuEHAAAAgCUQfgAAAABYAuEHAAAAgCUQfgAAAABYAuEHAAAAgCUQfoDzUN++fdW3b9+6LsNFbm6u/vjHP6px48ay2WyaNWtWtZbfuXOnbDabFi9ebE575JFHZLPZXNodPXpUkyZNUlhYmDw8PDR06FBJUlFRkW6//XY5nU7ZbDYlJyef2w4B9diLL76oDh06qEGDBgoMDKzrcs5Kq1atNGrUqLouo1JVfQ5ZQWWfy8CFxKuuCwDcZfHixRo9erTLtKZNm6pTp06aNGmS4uPj66gy9/nvf/+rGTNmuCU8TZgwQWvXrtXDDz8sp9OpHj161Oj6K/zzn//Uk08+qeTkZF122WVq0aKFJOnxxx/X4sWLNXnyZLVp00YRERFu2X5NWLZsmfLy8ghoF7Dvv/9er776qkaNGqVWrVrV6rZ//PFHjRo1SnFxcbr//vt10UUX1er2raCqzyEA9Z/NMAyjrosA3KEi/EydOlXh4eEyDEO5ublavHixvvvuO7399tsaNGhQXZdZqYrgkp6eXq3lfv31VzVt2lQPP/ywHnnkkRqtyel0KiYmRi+99NJZLb9z506Fh4crLS3N/Lb36NGjOnr0qHx8fMx2w4cP18cff6w9e/a4LN+rVy95eXnp448/Put9qC2DBg3St99+q507d9Z1KXCT1157TTfccIM2bNhQ62dp58+fr3Hjxik7O1tt27at1W3XpNLSUnl4eKhBgwZ1XcpJqvocsoLKPpeBCwlnfnDBi4+PdzlLMWbMGIWEhOhf//rXeRt+zkd5eXk1fnmNl5eXvLxcP4aq2k5eXp46duxYY9suLy/XkSNHOMDXgaNHj6q8vFze3t51XUq9lJeXJ0n19nK3Cna7va5LqJI7Pu/qi8o+l4ELCff8wHICAwPl6+t70od7cXGx7r33XoWFhclut6t9+/Z66qmnVHFy9PDhw+rQoYM6dOigw4cPm8sdPHhQzZo10xVXXKFjx45Vud3FixfLZrPpww8/1J133qnGjRsrICBAt956q3777bfT1p2Xl2cGNx8fH3Xt2lVLliwx5+/cuVNNmzaVJE2ZMkU2m002m+20Z4D+85//6IYbblBQUJAuuugi9erVS++8885JdRuGoblz55rrPZX8/HyNGjVKDodDgYGBGjlypPLz809q9/tryyvuCdqwYYO+++47czvp6emy2WzasWOH3nnnHXN6xVmV0tJSPfzww2rbtq3sdrvCwsI0adIklZaWumzLZrMpKSlJL7/8sjp16iS73a41a9ZIkvbu3avbbrtNISEhstvt6tSpk/75z3+6LF9Rx6uvvqrHHntMzZs3l4+PjwYMGKBt27aZ7fr27at33nlHP//8s1nr6S6LqqhtxYoV6tixo3x9fRUdHa1vvvlGkvTCCy+obdu28vHxUd++fSs9o7R582bFxcXJ4XDooosu0tVXX61PPvnEpc3PP/+sv/zlL2rfvr18fX3VuHFj3XDDDSetr6ysTFOmTFG7du3k4+Ojxo0bq0+fPlq3bp3LflZ2xuPEy8Aq/l+feuopzZo1S23atJHdbtf3338v6fglXH/84x8VFBQkHx8f9ejRQ2+99ZbLOit+Bz/++GPdfffdatq0qQIDA3XnnXfqyJEjys/P16233qpGjRqpUaNGmjRpkk68qKG8vFyzZs1Sp06d5OPjo5CQEN15550nvfdatWqlQYMG6eOPP9bll18uHx8ftW7dWkuXLnWp54YbbpAk9evXz+V3VZI+//xzxcbGqkmTJvL19VV4eLhuu+22k16ryjz//PPm72doaKgSExNd3jutWrXSww8/LOn4Zbyne4/n5ORo9OjRat68uex2u5o1a6YhQ4a4/J9X7PN7772nbt26ycfHRx07dtQbb7xx0vry8/OVnJxsfk62bdtW06dPV3l5uUu78vJyPfvss+rSpYt8fHzUtGlTxcXF6fPPP3fZ7on3/Jzp+pcvX67u3burYcOGCggIUJcuXfTss8+e5tU9/ef8qT6HqlLTr9/v3zMLFiww3zM9e/bUli1bTlpnxeeGj4+POnfurJUrV570Pqz4/DpxP870XsyKz6hVq1apc+fO5udkxWcoUK8YwAUqLS3NkGS8//77xi+//GLk5eUZ3377rXHnnXcaHh4exnvvvWe2LS8vN/r372/YbDbj9ttvN5577jlj8ODBhiQjOTnZbLdp0ybD09PTmDBhgjlt+PDhhq+vr7F169YzqqdLly7GlVdeacyePdtITEw0PDw8jKuuusooLy8321599dXG1VdfbY7/97//NSIiIowGDRoYEyZMMGbPnm1ceeWVhiRj1qxZhmEYRlFRkTFv3jxDknH99dcbL774ovHiiy8aX331VZU15eTkGCEhIUbDhg2Nv//978YzzzxjdO3a1fDw8DDeeOMNwzAMY/v27caLL75oSDL+8Ic/mOutSnl5uXHVVVcZHh4exl/+8hdjzpw5Rv/+/Y3IyEhDkpGWlma2ffjhh42Kj6GioiLjxRdfNDp06GA0b97c3E5OTo7x4osvGk2aNDG6detmTi8qKjKOHTtmDBw40LjooouM5ORk44UXXjCSkpIMLy8vY8iQIS51STIiIiKMpk2bGlOmTDHmzp1rfPnll0ZOTo7RvHlzIywszJg6daoxb94847rrrjMkGTNnzjSX37BhgyHJuPTSS43u3bsbM2fONB555BHjoosuMi6//HKz3XvvvWd069bNaNKkiVnrypUrq3y9KmqLjIw0wsLCjCeeeMJ44oknDIfDYbRo0cJ47rnnjI4dOxpPP/208eCDDxre3t5Gv379XJZfv3694e3tbURHRxtPP/20MXPmTCMyMtLw9vY2Nm/ebLZbsWKF0bVrV+Ohhx4yFixYYDzwwANGo0aNjJYtWxrFxcVmuwceeMCw2WzGHXfcYSxcuNB4+umnjZtuusl44oknzDYn/o5WGDlypNGyZUtzfMeOHYYko2PHjkbr1q2NJ554wpg5c6bx888/G99++63hcDiMjh07GtOnTzeee+4546qrrjJsNpv5+2cY///e6datmxEXF2fMnTvXuOWWWwxJxqRJk4w+ffoYN998s/H8888bgwYNMiQZS5Yscanr9ttvN7y8vIw77rjDmD9/vnHfffcZfn5+Rs+ePY0jR46Y7Vq2bGm0b9/eCAkJMR544AHjueeeMy677DLDZrMZ3377rWEYx98Td999tyHJeOCBB1x+V3Nzc41GjRoZl1xyifHkk08aCxcuNP7+978bERERp/wdMIz/fz/ExMQYc+bMMZKSkgxPT0+XGleuXGlcf/31hiRj3rx5p32PX3HFFYbD4TAefPBB4x//+Ifx+OOPG/369TMyMjJc9vmSSy4xAgMDjfvvv9945plnjC5dupz0OVlcXGxERkYajRs3Nh544AFj/vz5xq233mrYbDbjnnvucdnuqFGjDElGfHy8MWvWLOOpp54yhgwZYsyZM8dluyNHjqz2+t977z1DkjFgwABj7ty5xty5c42kpCTjhhtuOOXreyaf86f6HKpKTb9+Fe+ZSy+91Gjbtq0xffp0Y8aMGUaTJk2M5s2bu/y+rl692rDZbEZkZKTxzDPPGJMnTzYaNWpkdO7c2eV9WPH5tWHDBpfaK7ZV1edyBUlG165djWbNmhmPPvqoMWvWLKN169bGRRddZPz666+nfN2B8w3hBxesij+YThzsdruxePFil7arVq0yJBnTpk1zmf7HP/7RsNlsxrZt28xpKSkphoeHh/Hhhx8aK1ascAkgZ1JP9+7dXQ5eM2bMMCQZb775pjntxD8sZ82aZUgyXnrpJXPakSNHjOjoaMPf398oLCw0DMMwfvnlF0OS8fDDD5/Ra5ScnGxIMj766CNz2qFDh4zw8HCjVatWxrFjx8zpkozExMTTrrPitZwxY4Y57ejRo2ZYO91B9uqrrzY6dep00npbtmxpXHvttS7TXnzxRcPDw8OlfsMwjPnz5xuSjE8++cSlfg8PD+O7775zaTtmzBijWbNmJx3Ahw8fbjgcDuO///2vYRj//8dDRESEUVpaarZ79tlnDUnGN998Y0679tprXf7wOJ2K38sdO3aY01544QVDkuF0Os3/X8M4/vsnyWxbXl5utGvXzoiNjXUJ0P/973+N8PBw4w9/+IPLtBNt3LjRkGQsXbrUnNa1a9eTXusTVTf8BAQEGHl5eS5tBwwYYHTp0sUoKSkxp5WXlxtXXHGF0a5dO3NaxXvnxH2Mjo42bDabcdddd5nTjh49ajRv3tylto8++siQZLz88ssu21+zZs1J01u2bGlIMj788ENzWl5enmG32417773XnFbx3j/xj8mVK1cakowtW7ac9NqcSl5enuHt7W0MHDjQ5X333HPPGZKMf/7zn+a0ivfNL7/8csp1/vbbb4Yk48knnzxlu4p9fv31181pBQUFRrNmzYxLL73UnPboo48afn5+xk8//eSy/P333294enoau3btMgzDMD744ANDknH33XeftK3f//+dGH7OdP333HOPERAQYBw9evSU+3Wi6nzOV/U5VJmafv0q3jONGzc2Dh48aLZ78803DUnG22+/bU7r0qWL0bx5c+PQoUPmtPT0dENSjYcfb29vl9foq6++MiS5BFqgPuCyN1zw5s6dq3Xr1mndunV66aWX1K9fP91+++0ulyT8+9//lqenp+6++26XZe+9914ZhqF3333XnPbII4+oU6dOGjlypP7yl7/o6quvPmm5Uxk7dqzLDb7jxo2Tl5eX/v3vf1e5zL///W85nU7ddNNN5rQGDRro7rvvVlFRkTIyMs54+yeu9/LLL1efPn3Maf7+/ho7dqx27txpXppU3XV6eXlp3Lhx5jRPT0+NHz/+rGo8lRUrVigiIkIdOnTQr7/+ag79+/eXJG3YsMGl/dVXX+1y35BhGHr99dc1ePBgGYbhso7Y2FgVFBToiy++cFnH6NGjXe5VufLKKyUdv3zwXAwYMMDlMpWoqChJUkJCgho2bHjS9IrtZWVlKTs7WzfffLMOHDhg1l9cXKwBAwboww8/NC+p8fX1NddTVlamAwcOqG3btgoMDHTZz8DAQH333XfKzs4+p336vYSEBPOyTOn45aIffPCBbrzxRh06dMis+8CBA4qNjVV2drb27t3rso4xY8a4XI4TFRUlwzA0ZswYc5qnp6d69Ojh8v+xYsUKORwO/eEPf3D5P+7evbv8/f1P+j3p2LGj+f8qHb+8rH379mf0f1xxn8jq1atVVlZ2Zi+OpPfff19HjhxRcnKyPDz+/9B8xx13KCAgwOVS1DPl6+srb29vpaenn/bS2tDQUF1//fXmeMUluV9++aVycnIkHX8dr7zySjVq1MjldYyJidGxY8f04YcfSpJef/112Ww28/K83zvVJbNnuv7AwEAVFxe7XIZ5JqrzOV9dNfn6VfjTn/6kRo0ameMnftbs27dP33zzjW699Vb5+/ub7a6++mp16dLlrPelKjExMWrTpo05HhkZqYCAgHP+7ANqG3e04YJ3+eWXu3R4cNNNN+nSSy9VUlKSBg0aJG9vb/38888KDQ11+SNTktmd8s8//2xO8/b21j//+U/17NlTPj4+SktLq9YzEdq1a+cy7u/vr2bNmp2yZ7Cff/5Z7dq1c/mjqKr6quPnn382/5iuar2dO3eu9jqbNWvmcjCWpPbt259VjaeSnZ2tH374weWP6t+ruDG8Qnh4uMv4L7/8ovz8fC1YsEALFiw4o3Wc2OVtxR8nZ3Lf1qmcuF6HwyFJCgsLq3R6xfYqAsrIkSOrXHdBQYEaNWqkw4cPKzU1VWlpadq7d6/LfTEFBQXmz1OnTtWQIUN0ySWXqHPnzoqLi9Mtt9yiyMjIs96/E1/7bdu2yTAMTZ48WZMnT650mby8PF188cXmeHVeo9//f2RnZ6ugoEDBwcFVbuf3KuvWuFGjRmf0f3z11VcrISFBU6ZM0cyZM9W3b18NHTpUN9988ylv8K94D5/4PvH29lbr1q3P6j1ut9s1ffp03XvvvQoJCVGvXr00aNAg3XrrrXI6nS5t27Zte9Ln2CWXXCLp+H0hTqdT2dnZ+vrrr0/7ftu+fbtCQ0MVFBRUrXrPdP1/+ctf9Oqrryo+Pl4XX3yxBg4cqBtvvFFxcXGnXH91PuerqyZfvwqn+6ypqLeyHv/atm170hc35+pc3hfA+YTwA8vx8PBQv3799Oyzzyo7O1udOnWq9jrWrl0rSSopKVF2dvZJf9ihdpSXl6tLly565plnKp1/4h/Fvz/zUbG8JP35z3+uMjyc+Ae/p6dnpe1+HyTORlXrPd32KvbhySefVLdu3SptWxFEx48fr7S0NCUnJys6OloOh0M2m03Dhw93ueH6qquu0vbt2/Xmm2/qvffe0z/+8Q/NnDlT8+fP1+233y5JZicYJ6qq04+qXvu//vWvio2NrXSZE/+oq85r9PvaysvLFRwcrJdffrnS5U/8Y/Rc/o9tNptee+01bdq0SW+//bbWrl2r2267TU8//bQ2bdp00pcC7pacnKzBgwdr1apVWrt2rSZPnqzU1FR98MEHuvTSS6u1rvLycv3hD3/QpEmTKp1f8cf+2TrT9QcHBysrK0tr167Vu+++q3fffVdpaWm69dZbXTqBOd9U9/Wryc+aqr6gO1UnPSdy12cfUNsIP7Cko0ePSpKKiookSS1bttT777+vQ4cOuXwr+OOPP5rzK3z99deaOnWqRo8eraysLN1+++365ptvzG+hTyc7O1v9+vUzx4uKirR//35dc801VS7TsmVLff311yovL3c5+3NifdV9KnfLli21devWk6ZXtt/VWef69etVVFTk8odeZds5V23atNFXX32lAQMGnNUTyZs2baqGDRvq2LFjiomJqbG6avPp6BWXoQQEBJx2H1577TWNHDlSTz/9tDmtpKSk0p74goKCNHr0aI0ePVpFRUW66qqr9Mgjj5jhp1GjRpVe7nKm3563bt1a0vHLN2vyta9MmzZt9P7776t3794nhbCzdbr/4169eqlXr1567LHHtGzZMo0YMULLly83X78TVbzXtm7dar42knTkyBHt2LHjnF6jNm3a6N5779W9996r7OxsdevWTU8//bTLM7sqzsT9fr9++uknSTIvx2zTpo2KiopOW0ubNm20du1aHTx4sFpnf850/dLxM2KDBw/W4MGDVV5err/85S964YUXNHny5CqffVSdz/nqqsnX70xV1Pv73iZ/X8/vVZw1OvG9fi5nu4D6int+YDllZWV677335O3tbV7ucM011+jYsWN67rnnXNrOnDlTNptN8fHx5rKjRo1SaGionn32WS1evFi5ubmaMGHCGW9/wYIFLvcCzJs3T0ePHjW3UZlrrrlGOTk5euWVV8xpR48e1Zw5c+Tv76+rr75akswnvVf2x2xV6/3ss8+0ceNGc1pxcbEWLFigVq1andVzda655hodPXpU8+bNM6cdO3ZMc+bMqfa6TufGG2/U3r17tXDhwpPmHT58WMXFxadc3tPTUwkJCXr99df17bffnjT/l19+Oau6/Pz8XC4jc6fu3burTZs2euqpp8ww/3u/3wdPT8+TvqWdM2fOSd/+HjhwwGXc399fbdu2dek+vE2bNvrxxx9d1v/VV1+d1L12VYKDg9W3b1+98MIL2r9//ynrPlc33nijjh07pkcfffSkeUePHj3j98vv+fn5STr5vfbbb7+d9BpXnJE7sfv134uJiZG3t7dmz57tsvyiRYtUUFCga6+9tto1/ve//1VJSYnLtDZt2qhhw4Yn1bJv3z6tXLnSHC8sLNTSpUvVrVs38xK5G2+8URs3bjTPfP9efn6++aVSQkKCDMPQlClTTmp3qrMEZ7r+E38/PTw8zDO0p3qNz/Rz/mzU5Ot3pkJDQ9W5c2ctXbrU5b2fkZFhdpNfoWXLlvL09DzpvqLnn3++WtsELgSc+cEF79133zW/2cvLy9OyZcuUnZ2t+++/XwEBAZKkwYMHq1+/fvr73/+unTt3qmvXrnrvvff05ptvKjk52fx2fdq0acrKytL69evVsGFDRUZG6qGHHtKDDz6oP/7xj6c8e1PhyJEjGjBggG688UZt3bpVzz//vPr06aPrrruuymXGjh2rF154QaNGjVJmZqZatWql1157TZ988olmzZplfovp6+urjh076pVXXtEll1yioKAgde7cucr7du6//37961//Unx8vO6++24FBQVpyZIl2rFjh15//fWT7jE6E4MHD1bv3r11//33a+fOnebzLtwRBm655Ra9+uqruuuuu7Rhwwb17t1bx44d048//qhXX31Va9eudbnfqzJPPPGENmzYoKioKN1xxx3q2LGjDh48qC+++ELvv/++Dh48WO26unfvrldeeUUTJ05Uz5495e/vr8GDB5/tbp6Sh4eH/vGPfyg+Pl6dOnXS6NGjdfHFF2vv3r3asGGDAgIC9Pbbb0uSBg0apBdffFEOh0MdO3bUxo0b9f7776tx48Yu6+zYsaP69u2r7t27KygoSJ9//rlee+01JSUlmW1uu+02PfPMM4qNjdWYMWOUl5en+fPnq1OnTiosLDyj2ufOnas+ffqoS5cuuuOOO9S6dWvl5uZq48aN2rNnj7766qsaeY2uvvpq3XnnnUpNTVVWVpYGDhyoBg0aKDs7WytWrNCzzz6rP/7xj9VaZ7du3eTp6anp06eroKBAdrtd/fv317Jly/T888/r+uuvV5s2bXTo0CEtXLhQAQEBp/x8aNq0qVJSUjRlyhTFxcXpuuuuMz8fevbsqT//+c/V3u+ffvrJ/Kzp2LGjvLy8tHLlSuXm5mr48OEubS+55BKNGTNGW7ZsUUhIiP75z38qNzdXaWlpZpu//e1veuuttzRo0CCNGjVK3bt3V3Fxsb755hu99tpr2rlzp5o0aaJ+/frplltu0ezZs5Wdna24uDiVl5fro48+Ur9+/Vx+j37vTNd/++236+DBg+rfv7+aN2+un3/+WXPmzFG3bt3ML7Qqc6af82ejJl+/6nj88cc1ZMgQ9e7dW6NHj9Zvv/2m5557Tp07d3YJRA6HQzfccIPmzJkjm82mNm3aaPXq1SfdZwRYQq32LQfUosq6uvbx8TG6detmzJs3z6XLVcM43sXzhAkTjNDQUKNBgwZGu3btjCeffNJsl5mZaXh5eRnjx493We7o0aNGz549jdDQUOO33347bT0ZGRnG2LFjjUaNGhn+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3323lixZIknKycmRJIWEhLgsFxISYs47UUpKigoKCsxh9+7dNV02AAAAgAtcjV/2Vl5erh49eujxxx+XJF166aX69ttvNX/+fI0cOfKs1mm322W322uyTAAAAAAWU+Php1mzZurYsaPLtIiICL3++uuSJKfTKUnKzc1Vs2bNzDa5ubnq1q1bTZcDuNXhI8e0/Zeiai1TUnZMe347rOaNfOXTwLPa22zT1F++3tVfDgBgDbV9bOK4hPqkxsNP7969tXXrVpdpP/30k1q2bCnpeOcHTqdT69evN8NOYWGhNm/erHHjxtV0OYBbbf+lSIPmfFyr21w9vo86X+yo1W0CAOqP2j42cVxCfVLj4WfChAm64oor9Pjjj+vGG2/UZ599pgULFmjBggWSJJvNpuTkZE2bNk3t2rVTeHi4Jk+erNDQUA0dOrSmywHcqk1Tf60e36day2zLK1LyK1ma9aduahvsf1bbBACgKrV9bOK4hPqkxsNPz549tXLlSqWkpGjq1KkKDw/XrFmzNGLECLPNpEmTVFxcrLFjxyo/P199+vTRmjVr5OPjU9PlAG7l6+151t92tQ3255syAECN49gEVK3Gw48kDRo0SIMGDapyvs1m09SpUzV16lR3bB4AAAAATlLjXV0DAAAAwPmI8AMAAADAEgg/AAAAACyB8AMAAADAEgg/AAAAACyB8AMAAADAEgg/AAAAACyB8AMAAADAEgg/AAAAACyB8AMAAADAEgg/AAAAACyB8AMAAADAEgg/AAAAACyB8AMAAADAEgg/AAAAACyB8AMAAADAEgg/AAAAACyB8AMAAADAEgg/AAAAACyB8AMAAADAEgg/AAAAACyB8AMAAADAEgg/AAAAACyB8AMAAADAEgg/AAAAACyB8AMAAADAEgg/AAAAACyB8AMAAADAEgg/AAAAACyB8AMAAADAEgg/AAAAACyB8AMAAADAEgg/AAAAACyB8AMAAADAEgg/AAAAACyhxsPPI488IpvN5jJ06NDBnD9q1KiT5sfFxdV0GQAAAADgwssdK+3UqZPef//9/9+Il+tm4uLilJaWZo7b7XZ3lAEAAAAAJreEHy8vLzmdzirn2+32U84/UWlpqUpLS83xwsLCc6oPAAAAgPW45Z6f7OxshYaGqnXr1hoxYoR27drlMj89PV3BwcFq3769xo0bpwMHDpxyfamp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C9Prr78uSdq6dav279+vZ5991mW//fz8tHnzZs2YMUNTp07VunXrzngfHn30Ud16663KyspShw4ddPPNN+vOO+9USkqKPv/8cxmGcdL+bN++Xe+++67WrFmjf/3rX1q0aJGuvfZa7dmzRxkZGZo+fboefPBBbd68udqvKQBcaGrj+LR7924NGzZMgwcPVlZWlm6//Xbdf//9Lm3O9Jj15JNPqmvXrvryyy91//3365577jGPK1u2bJEkpaWlaf/+/eZ4xfpXrVql1atXa/Xq1crIyNATTzxxxvuwZMkSNWnSRJ999pnGjx+vcePG6YYbbtAVV1yhL774QgMHDtQtt9xyUpB55JFH9Nxzz+nTTz/V7t27deONN2rWrFlatmyZ3nnnHb333nuaM2dOtV5PWJQB1BNXX321ERERYZSXl5vT7rvvPiMiIsIwDMNo2bKlMXPmTHOeJGPlypWGYRjGjh07DEnGl19+edrtbNiwwZBk/Pbbb4ZhGMaYMWOMsWPHurT56KOPDA8PD+Pw4cPmtv/85z+b88vLy43g4GBj3rx5hmEYxrx584zGjRub7Q3DMBYuXOhS04nb/f1+9+nTx2Vaz549jfvuu++0+2IYx1+HBx980BzfuHGjIclYtGiROe1f//qX4ePjY44//PDDxkUXXWQUFhaa02JjY41WrVoZx44dM6e1b9/eSE1NPaM6AOBCVVvHp5SUFKNjx44u0+67776zOmbFxcW5tPnTn/5kxMfHV1pjhcqODX/729+MqKio09ZuGCcfz44ePWr4+fkZt9xyizlt//79hiRj48aNhmH8/7Hx/fffN9ukpqYakozt27eb0+68804jNjb2jOqAtXHmB/VKr169ZLPZzPHo6GhlZ2fr2LFjbtvmV199pcWLF8vf398cYmNjVV5erh07dpjtIiMjzZ9tNpucTqfy8vIkHT+bExkZKR8fH7PN5ZdffsY1/H7dktSsWTNz3dVdPiQkRJLUpUsXl2klJSUqLCw0p7Vq1UoNGzZ0adOxY0d5eHi4TKtOHQBwoaqN49MPP/ygqKgol2nR0dEu42d6zDpxuejoaP3www+nreHEY8O5HI88PT3VuHHjk45Hkk5a54nHsYsuukitW7d2mcbxCGeCDg+A0ygqKtKdd96pu++++6R5LVq0MH9u0KCByzybzaby8vIaqeFc1/375SsOzpVN+/06K9umO/cRAHDuzvSYdbZq8nhUsfzpjkcnLsfxCOeC8IN65cT7SzZt2qR27drJ09PTbdu87LLL9P3336tt27ZnvY727dvrpZdeUmlpqex2uyS5XEMtSd7e3pLk1rNYAAD3qI3jU0REhN56662TtvN7Z3rMOnG5TZs2KSIiwhxv0KABxyNckLjsDfXKrl27NHHiRG3dulX/+te/NGfOHN1zzz1u3eZ9992nTz/9VElJScrKylJ2drbefPPNk24ePZWbb75Z5eXlGjt2rH744QetXbtWTz31lKT//5arZcuWstlsWr16tX755RcVFRW5ZX8AADWvNo5Pd911l7Kzs/W3v/1NW7du1bJly7R48WKXNmd6zPrkk080Y8YM/fTTT5o7d65WrFjhUm+rVq20fv165eTk6LfffqvR/QDqEuEH9cqtt96qw4cP6/LLL1diYqLuuecejR071q3bjIyMVEZGhn766SddeeWVuvTSS/XQQw8pNDT0jNcREBCgt99+W1lZWerWrZv+/ve/66GHHpIk8z6giy++WFOmTNH999+vkJCQaoUrAEDdqo3jU4sWLfT6669r1apV6tq1q+bPn6/HH3/cpc2ZHrPuvfdeff7557r00ks1bdo0PfPMM4qNjTXnP/3001q3bp3CwsJ06aWX1uh+AHXJZhj/64QeQK16+eWXNXr0aBUUFMjX17euywEAWESrVq2UnJys5OTkui4FqHXc8wPUkqVLl6p169a6+OKL9dVXX+m+++7TjTfeSPABAACoJVz2Bsu56667XLoA/f1w1113uW27OTk5+vOf/6yIiAhNmDBBN9xwgxYsWHBO63z55Zer3JdOnTrVUOUAgNpQV8enmrBr164qa/f399euXbvqukRAEpe9wYLy8vJcnmfzewEBAQoODq7lis7eoUOHlJubW+m8Bg0aqGXLlrVcEQDgbNXn49PRo0e1c+fOKue3atVKXl5ccIS6R/gBAAAAYAlc9gYAAADAEgg/AAAAACyB8AMAAADAEgg/AAAAACyB8AMAAADAEgg/AAAAACyB8AMAAADAEgg/AAAAACyB8AMAAADAEgg/AAAAACyB8AMAAADAEgg/AAAAACyB8AMAAADAEgg/AAAAACyB8AMAAADAEgg/AAAAACyB8AMAAADAEgg/AAAAACyB8AMAAADAEgg/AAAAACyB8AMAAADAEgg/AAAAACyB8AMAAADAEgg/AAAAACyB8AMAAADAEgg/AAAAACyB8AMAAADAEgg/AAAAACzBq64LOBvl5eXat2+fGjZsKJvNVtflAIClGIahQ4cOKTQ0VB4efIdWgWMTANSN6hyX6mX42bdvn8LCwuq6DACwtN27d6t58+Z1XcZ5g2MTANStMzku1cvw07BhQ0nHdzAgIKCOqwEAayksLFRYWJj5WYzjODYBQN2oznGpXoafissJAgICOMAAQB3h0i5XHJsAoG6dyXGJi7UBAAAAWALhBwAAAIAlEH4AAAAAWALhBwAAAIAlEH4AAAAAWALhBwAAAIAlEH4AAAAAWALhBwAAAIAlEH4AAAAAWIJXXRcA1GeHjxzT9l+KqrVMSdkx7fntsJo38pVPA89qb7NNU3/5eld/OQCANdT2sYnjEuoTwg9wDrb/UqRBcz6u1W2uHt9HnS921Oo2AQD1R20fmzguoT6pVvhJTU3VG2+8oR9//FG+vr664oorNH36dLVv395s88gjj2j58uXavXu3vL291b17dz322GOKiooy25SUlOjee+/V8uXLVVpaqtjYWD3//PMKCQmpuT0DakGbpv5aPb5PtZbZllek5FeyNOtP3dQ22P+stgkAQFVq+9jEcQn1SbXCT0ZGhhITE9WzZ08dPXpUDzzwgAYOHKjvv/9efn5+kqRLLrlEzz33nFq3bq3Dhw9r5syZGjhwoLZt26amTZtKkiZMmKB33nlHK1askMPhUFJSkoYNG6ZPPvmk5vcQcCNfb8+z/rarbbA/35QBAGocxyagatUKP2vWrHEZX7x4sYKDg5WZmamrrrpKknTzzTe7tHnmmWe0aNEiff311xowYIAKCgq0aNEiLVu2TP3795ckpaWlKSIiQps2bVKvXr1O2m5paalKS0vN8cLCwuqUDQAAAADn1ttbQUGBJCkoKKjS+UeOHNGCBQvkcDjUtWtXSVJmZqbKysoUExNjtuvQoYNatGihjRs3Vrqe1NRUORwOcwgLCzuXsgEAAABY0FmHn/LyciUnJ6t3797q3Lmzy7zVq1fL399fPj4+mjlzptatW6cmTZpIknJycuTt7a3AwECXZUJCQpSTk1PptlJSUlRQUGAOu3fvPtuyAQAAAFjUWff2lpiYqG+//VYff3xybyL9+vVTVlaWfv31Vy1cuFA33nijNm/erODg4LPalt1ul91uP9tSAQAAAODszvwkJSVp9erV2rBhg5o3b37SfD8/P7Vt21a9evXSokWL5OXlpUWLFkmSnE6njhw5ovz8fJdlcnNz5XQ6z6YcAAAAADitaoUfwzCUlJSklStX6oMPPlB4ePgZLVdeXm52WNC9e3c1aNBA69evN+dv3bpVu3btUnR0dHXKAQAAAIAzVq3L3hITE7Vs2TK9+eabatiwoXmPjsPhkK+vr4qLi/XYY4/puuuuU7NmzfTrr79q7ty52rt3r2644Qaz7ZgxYzRx4kQFBQUpICBA48ePV3R0dKU9vQEAAABATahW+Jk3b54kqW/fvi7T09LSNGrUKHl6eurHH3/UkiVL9Ouvv6px48bq2bOnPvroI3Xq1MlsP3PmTHl4eCghIcHlIacAAAAA4C7VCj+GYZxyvo+Pj954443TrsfHx0dz587V3Llzq7N5AAAAADhr5/ScHwAAAACoLwg/AAAAACyB8AMAAADAEgg/AAAAACyB8AMAAADAEgg/AIDz2t69e/XnP/9ZjRs3lq+vr7p06aLPP//cnG8Yhh566CE1a9ZMvr6+iomJUXZ2tss6SkpKlJiYqMaNG8vf318JCQnKzc11aXPw4EGNGDFCAQEBCgwM1JgxY1RUVFQr+wgAqB2EHwDAeeu3335T79691aBBA7377rv6/vvv9fTTT6tRo0ZmmxkzZmj27NmaP3++Nm/eLD8/P8XGxqqkpMRsM2HCBL399ttasWKFMjIytG/fPg0bNsxlWyNGjNB3332ndevWafXq1frwww81duzYWttXAID7Ves5PwAA1Kbp06crLCxMaWlp5rTw8HDzZ8MwNGvWLD344IMaMmSIJGnp0qUKCQnRqlWrNHz4cBUUFGjRokVatmyZ+vfvL+n4w7kjIiK0adMm9erVSz/88IPWrFmjLVu2qEePHpKkOXPm6JprrtFTTz2l0NDQWtxrAIC7cOYHAHDeeuutt9SjRw/dcMMNCg4O1qWXXqqFCxea83fs2KGcnBzFxMSY0xwOh6KiorRx40ZJUmZmpsrKylzadOjQQS1atDDbbNy4UYGBgWbwkaSYmBh5eHho8+bNldZWWlqqwsJClwEAcH4j/AAAzlv/+c9/NG/ePLVr105r167VuHHjdPfdd2vJkiWSpJycHElSSEiIy3IhISHmvJycHHl7eyswMPCUbYKDg13me3l5KSgoyGxzotTUVDkcDnMICws75/0FALgX4QcAcN4qLy/XZZddpscff1yXXnqpxo4dqzvuuEPz58+v69KUkpKigoICc9i9e3ddlwQAOA3CDwDgvNWsWTN17NjRZVpERIR27dolSXI6nZJ0Us9tubm55jyn06kjR44oPz//lG3y8vJc5h89elQHDx4025zIbrcrICDAZQAAnN8IPwCA81bv3r21detWl2k//fSTWrZsKel45wdOp1Pr16835xcWFmrz5s2Kjo6WJHXv3l0NGjRwabN161bt2rXLbBMdHa38/HxlZmaabT744AOVl5crKirKbfsHAKhd9PYGADhvTZgwQVdccYUef/xx3Xjjjfrss8+0YMECLViwQJJks9mUnJysadOmqV27dgoPD9fkyZMVGhqqoUOHSjreAcKYMWM0ceJEBQUFKSAgQOPHj1d0dLR69eol6fjZpLi4OPOSurKyMiUlJWn48OH09AYAFxDCDwDgvNWzZ0+tXLlSKSkpmjp1qsLDwzVr1iyNGDHCbDNp0iQVFxdr7Nixys/PV58+fbRmzRr5+PiYbWbOnCkPDw8lJCSotLRUsbGxev7551229fLLLyspKUkDBgww286ePbvW9hUA4H42wzCMui6iugoLC+VwOFRQUMA11qh3vt1boEFzPtbq8X3U+WJHXZcDVBufwZXjdUF9xrEJ9Vl1Pn+55wcAAACAJRB+AAAAAFgC4QcAAACAJRB+AAAAAFgC4QcAAACAJRB+AAAAAFgC4QcAAACAJRB+AAAAAFgC4QcAAACAJRB+AAAAAFgC4QcAAACAJRB+AAAAAFgC4QcAAACAJRB+AAAAAFgC4QcAAACAJRB+AAAAAFhCtcJPamqqevbsqYYNGyo4OFhDhw7V1q1bzfllZWW677771KVLF/n5+Sk0NFS33nqr9u3b57KekpISJSYmqnHjxvL391dCQoJyc3NrZo8AAAAAoBLVCj8ZGRlKTEzUpk2btG7dOpWVlWngwIEqLi6WJP33v//VF198ocmTJ+uLL77QG2+8oa1bt+q6665zWc+ECRP09ttva8WKFcrIyNC+ffs0bNiwmtsrAAAAADiBV3Uar1mzxmV88eLFCg4OVmZmpq666io5HA6tW7fOpc1zzz2nyy+/XLt27VKLFi1UUFCgRYsWadmyZerfv78kKS0tTREREdq0aZN69ep10nZLS0tVWlpqjhcWFlanbAAAAAA4t3t+CgoKJElBQUGnbGOz2RQYGChJyszMVFlZmWJiYsw2HTp0UIsWLbRx48ZK15GamiqHw2EOYWFh51I2AAAAAAs66/BTXl6u5ORk9e7dW507d660TUlJie677z7ddNNNCggIkCTl5OTI29vbDEMVQkJClJOTU+l6UlJSVFBQYA67d+8+27IBAAAAWFS1Lnv7vcTERH377bf6+OOPK51fVlamG2+8UYZhaN68eWddoCTZ7XbZ7fZzWgcAAAAAazurMz9JSUlavXq1NmzYoObNm580vyL4/Pzzz1q3bp151keSnE6njhw5ovz8fJdlcnNz5XQ6z6YcAAAAADitaoUfwzCUlJSklStX6oMPPlB4ePhJbSqCT3Z2tt5//301btzYZX737t3VoEEDrV+/3py2detW7dq1S9HR0We5GwAAAABwatW67C0xMVHLli3Tm2++qYYNG5r36DgcDvn6+qqsrEx//OMf9cUXX2j16tU6duyY2SYoKEje3t5yOBwaM2aMJk6cqKCgIAUEBGj8+PGKjo6utKc3AAAAAKgJ1TrzM2/ePBUUFKhv375q1qyZObzyyiuSpL179+qtt97Snj171K1bN5c2n376qbmemTNnatCgQUpISNBVV10lp9OpN954o2b3DABQ7z3yyCOy2WwuQ4cOHcz5o0aNOml+XFycyzrO5MHaBw8e1IgRIxQQEKDAwECNGTNGRUVFtbKPAIDaU60zP4ZhnHJ+q1atTttGknx8fDR37lzNnTu3OpsHAFhQp06d9P7775vjXl6uh664uDilpaWZ4yd2kDNhwgS98847WrFihRwOh5KSkjRs2DB98sknZpsRI0Zo//795gO8R48erbFjx2rZsmVu2isAQF04697eAACoDV5eXqfsEMdut1c5/0werP3DDz9ozZo12rJli3r06CFJmjNnjq655ho99dRTCg0NrXTdPIAbAOqfc3rIKQAA7padna3Q0FC1bt1aI0aM0K5du1zmp6enKzg4WO3bt9e4ceN04MABc96ZPFh748aNCgwMNIOPJMXExMjDw0ObN2+usi4ewA0A9Q/hBwBw3oqKitLixYu1Zs0azZs3Tzt27NCVV16pQ4cOSTp+ydvSpUu1fv16TZ8+XRkZGYqPj9exY8ckndmDtXNychQcHOwy38vL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"
+ },
+ "metadata": {}
+ }
]
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"---\n",
"\n",
@@ -207,193 +319,241 @@
"Exercise: Compare bill length of different species of penguin\n",
" \n",
""
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
- "Let's use box plot to compare the bill length of different species of penguin. We need the DataFrame to be slightly different so we can compare the different type species of penguin. We would like to pivot the data so each column are bill length of different species of penguin."
- ]
+ "Let's use box plot to compare the bill length of different species of penguin. We need the DataFrame to be slightly different so we can compare the different species of penguin. We would like to pivot the data so each column are bill length of different species of penguin."
+ ],
+ "metadata": {}
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"#### Prepare the data set"
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "df_pivot = df.pivot(index=None, columns='species', values='bill_length_mm')\n",
+ "# tell the pivot() method to make the 'species' as columns, and using the 'bill_length_mm' as the value"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "df_pivot = df.pivot(index=None, columns='species', values='bill_length_mm')\n",
- "# tell the pivot() method to make the 'species' as columns, and using the 'bill_length_mm' as the value"
- ]
+ "execution_count": 8,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "df_pivot.sample(10)"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "df_pivot.sample(10)"
+ "execution_count": 9,
+ "outputs": [
+ {
+ "execution_count": 9,
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": "species Adelie Chinstrap Gentoo\n200 NaN 51.5 NaN\n180 NaN 46.4 NaN\n136 35.6 NaN NaN\n30 39.5 NaN NaN\n199 NaN 49.0 NaN\n337 NaN NaN 48.8\n165 NaN 52.0 NaN\n129 44.1 NaN NaN\n194 NaN 50.9 NaN\n155 NaN 45.4 NaN",
+ "text/html": "
\n\n
\n \n
\n
species
\n
Adelie
\n
Chinstrap
\n
Gentoo
\n
\n \n \n
\n
200
\n
NaN
\n
51.5
\n
NaN
\n
\n
\n
180
\n
NaN
\n
46.4
\n
NaN
\n
\n
\n
136
\n
35.6
\n
NaN
\n
NaN
\n
\n
\n
30
\n
39.5
\n
NaN
\n
NaN
\n
\n
\n
199
\n
NaN
\n
49.0
\n
NaN
\n
\n
\n
337
\n
NaN
\n
NaN
\n
48.8
\n
\n
\n
165
\n
NaN
\n
52.0
\n
NaN
\n
\n
\n
129
\n
44.1
\n
NaN
\n
NaN
\n
\n
\n
194
\n
NaN
\n
50.9
\n
NaN
\n
\n
\n
155
\n
NaN
\n
45.4
\n
NaN
\n
\n \n
\n
"
+ },
+ "metadata": {}
+ }
]
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"#### Box plot of df_pivot\n",
"\n",
"Now we can use `plot()` on `df_pivot`. To make a box plot, remember to set the parameter `kind` to 'box'. Also make the presentation nice by setting a good `figsize` and with a good `title`. Don't forget the `legend`."
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false
},
- "outputs": [],
- "source": []
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"#### Additional exercise\n",
"\n",
"Challenge yourself by making your own `df_pivot` pivoting on a different measure (e.g. Body Mass). Also try using a histogram (hist) instead of a boxplot. You can also try making a plot with 3 subplots, each is a histogram of a type of penguin."
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false
},
- "outputs": [],
- "source": []
+ "execution_count": null,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"So far we are not using `matplotlib.pyplot` directly. Although it is very convenient to use `df.plot()`, sometimes we would like to have more control with what we are plotting and make more complex graphs. In the following sections, we will use `matplotlib.pyplot` (which is imported as `plt` now) directly."
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
- "### Divide the data into 3 types accordingly"
- ]
+ "### Divide the data into 3 types accordingly\n",
+ "\n",
+ "In order to create the following plots, we need to create different pandas DataFrames for each penguin species."
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "df['species'].unique()"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "df['species'].unique()"
+ "execution_count": 10,
+ "outputs": [
+ {
+ "execution_count": 10,
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": "array(['Adelie', 'Chinstrap', 'Gentoo'], dtype=object)"
+ },
+ "metadata": {}
+ }
]
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "df_adelie = df[df['species'] == 'Adelie']"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "df_adelie = df[df['species'] == 'Adelie']"
- ]
+ "execution_count": 11,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "df_chinstrap = df[df['species'] == 'Chinstrap']"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "df_chinstrap = df[df['species'] == 'Chinstrap']"
- ]
+ "execution_count": 12,
+ "outputs": []
},
{
"cell_type": "code",
- "execution_count": null,
+ "source": [
+ "df_gentoo = df[df['species'] == 'Gentoo']"
+ ],
"metadata": {
"jupyter": {
"outputs_hidden": false
- }
+ },
+ "collapsed": false,
+ "trusted": true
},
- "outputs": [],
- "source": [
- "df_gentoo = df[df['species'] == 'Gentoo']"
- ]
+ "execution_count": 13,
+ "outputs": []
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
"### Scatter plot example: plot on Bill Length and Width"
- ]
+ ],
+ "metadata": {}
},
{
"cell_type": "code",
- "execution_count": null,
- "metadata": {
- "jupyter": {
- "outputs_hidden": false
- }
- },
- "outputs": [],
"source": [
"plt.scatter(df_adelie['bill_length_mm'], df_adelie['bill_depth_mm'], c='r')\n",
"plt.scatter(df_chinstrap['bill_length_mm'], df_chinstrap['bill_depth_mm'], c='g')\n",
"plt.scatter(df_gentoo['bill_length_mm'], df_gentoo['bill_depth_mm'], c='b')"
+ ],
+ "metadata": {
+ "jupyter": {
+ "outputs_hidden": false
+ },
+ "collapsed": false,
+ "trusted": true
+ },
+ "execution_count": 14,
+ "outputs": [
+ {
+ "execution_count": 14,
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": ""
+ },
+ "metadata": {}
+ },
+ {
+ "output_type": "display_data",
+ "data": {
+ "text/plain": "