From 2f19575eb524f13fc5f56771723bb64cd7f2f44b Mon Sep 17 00:00:00 2001 From: Heurich <manueh51@mars.imp.fu-berlin.de> Date: Fri, 8 Oct 2021 12:14:48 +0200 Subject: [PATCH] Add first assignment and intros --- Assignment01_nb.ipynb | 237 ++++ Pandas_intro.ipynb | 2776 ++++++++++++++++++++++++++++++++++++++ Python_numpy_intro.ipynb | 2500 ++++++++++++++++++++++++++++++++++ 3 files changed, 5513 insertions(+) create mode 100644 Assignment01_nb.ipynb create mode 100644 Pandas_intro.ipynb create mode 100644 Python_numpy_intro.ipynb diff --git a/Assignment01_nb.ipynb b/Assignment01_nb.ipynb new file mode 100644 index 0000000..89bb6d2 --- /dev/null +++ b/Assignment01_nb.ipynb @@ -0,0 +1,237 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "484313d8-8a62-44ed-801e-6e2d903194e7", + "metadata": { + "tags": [] + }, + "source": [ + "# Assignment Sheet 1 " + ] + }, + { + "cell_type": "markdown", + "id": "2dbfe254-4f29-4fbe-a465-3cd86ac7dfb4", + "metadata": {}, + "source": [ + "## Task 4 - Bivariate Descriptors" + ] + }, + { + "cell_type": "markdown", + "id": "52435766-3f59-42f8-aea4-fbddc841d4e6", + "metadata": {}, + "source": [ + "This notebook complements task 4 using the pandas library.\n", + "\n", + "The comments in each cell describe each small task you should complete. :)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3c55209e-7c80-4e45-8ee7-1d49f9c0b1c9", + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd" + ] + }, + { + "cell_type": "markdown", + "id": "80fcaacc-4a91-43f3-bd05-315769c3e8be", + "metadata": {}, + "source": [ + "### a) Heart Dataset" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4822bf49-37e8-49c8-8bb0-658b7bca611b", + "metadata": {}, + "outputs": [], + "source": [ + "# Dataset: https://www.kaggle.com/ronitf/heart-disease-uci/download\n", + "df = pd.read_csv('your/path/to/heart.csv')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d17d2f78-21fe-495f-8501-c6dc7d5bdec0", + "metadata": {}, + "outputs": [], + "source": [ + "# Take the first 8 rows of the dataframe\n", + "small_df = df.head(8)\n", + "small_df" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f8d417c2-426d-4ce4-ac83-ac94b765107c", + "metadata": {}, + "outputs": [], + "source": [ + "# Check std of each feature of the partial dataframe" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c0cc68a9-f0d4-4f53-97f7-cdff7358fbfd", + "metadata": {}, + "outputs": [], + "source": [ + "# Check mean of each feature of the partial dataframe" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "477dbb53-3570-4287-8367-98d711ad280e", + "metadata": {}, + "outputs": [], + "source": [ + "# Calculate correlation for each feature in the dataframe" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2e90cd02-3152-435b-98ee-05bc18c6c715", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "id": "c5d4157a-f01d-49e2-bbc5-4a9c47572b6c", + "metadata": {}, + "source": [ + "### b) Titanic Dataset (train.csv)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "974508fe-0a81-444d-b296-2ce613d1df3c", + "metadata": {}, + "outputs": [], + "source": [ + "# Dataset: https://www.kaggle.com/c/titanic/data?select=train.csv\n", + "df = pd.read_csv('your/path/to/titanic/train.csv')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "76a8b05d-9afc-4bef-b31d-f94853810391", + "metadata": {}, + "outputs": [], + "source": [ + "# Take the first 16 rows of the dataframe" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9f069ec6-900b-4004-adcb-a2da8b95ff4e", + "metadata": {}, + "outputs": [], + "source": [ + "# Show number of instances for male/female passengers" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0d9082fc-9da0-4e5b-8f0b-b681d46b7813", + "metadata": {}, + "outputs": [], + "source": [ + "# Show number of instances for each passenger class" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c7a1ea7e-c708-417f-9d8f-e19448b0880b", + "metadata": {}, + "outputs": [], + "source": [ + "# Filter and print every contingency table entry for the Chi-Square calculation\n", + "# The features to check are 'Sex' and 'Pclass', equally to Task 4 on the exercise sheet" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "643731b9-01e7-40af-90e3-5dc6bd2415ae", + "metadata": {}, + "outputs": [], + "source": [ + "# Calculate and print your Chi-Square solution for the\n", + "## Expected Values\n", + "### male and class1\n", + "m_c1 = \n", + "### male and class2\n", + "m_c2 = \n", + "### male and class3\n", + "m_c3 = \n", + "### female and class1\n", + "f_c1 = \n", + "### female and class2\n", + "f_c2 = \n", + "### female and class3\n", + "f_c3 = \n", + "\n", + "print('Expected values of the contingency matrix')\n", + "print(m_c1,' | ', f_c1)\n", + "print('--'*8)\n", + "print(m_c2,' | ', f_c2)\n", + "print('--'*8)\n", + "print(m_c3,' | ', f_c3)\n", + "\n", + "## chi-square calculation\n", + "chi_square = \n", + "\n", + "print('--'*8)\n", + "print('--'*8)\n", + "print('X^2 = ', chi_square)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "794dc6f4-7b1e-44bf-b704-69291dc173b6", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.9" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/Pandas_intro.ipynb b/Pandas_intro.ipynb new file mode 100644 index 0000000..5685f49 --- /dev/null +++ b/Pandas_intro.ipynb @@ -0,0 +1,2776 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Data Mining I - Tutorial 2\n", + "\n", + "In this second tutorial we will have a look at the pandas library and how to use it to get to know your data. Again, this tutorial only covers a few basics and is far from complete. You can find more detailed tutorials\n", + "[here](https://pandas.pydata.org/pandas-docs/stable/getting_started/tutorials.html). There is also a nice \n", + "[Cheatsheet](http://pandas.pydata.org/Pandas_Cheat_Sheet.pdf) available.\n", + "\n", + "Lets get started by importing pandas:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "*The pandas library provides high-performance, easy-to-use data structures and data analysis tools. The main data structure is the DataFrame, which you can think of as an in-memory 2D table (like a spreadsheet, with column names and row labels). Many features available in Excel are available programmatically, such as creating pivot tables, computing columns based on other columns, plotting graphs, etc. You can also group rows by column value, or join tables much like in SQL. Pandas is also great at handling time series.*\n", + "\n", + "The two useful data structures we will mainly use are:\n", + "* [Series](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.html#pandas.Series) objects. A Series object is a 1D array, similar to a column in a spreadsheet (with a column name and row labels).\n", + "* [DataFrame](https://pandas.pydata.org/pandas-docs/stable/reference/frame.html) objects. This is a 2D table, similar to a spreadsheet (with column names and row labels)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Series\n", + "We can create series objects in many different ways. To get an overview of all the options, have a look at the [documentation](https://pandas.pydata.org/pandas-docs/stable/getting_started/dsintro.html#dsintro)." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0 1\n", + "1 3\n", + "2 5\n", + "3 1\n", + "4 6\n", + "5 8\n", + "dtype: int64\n", + "alice 1\n", + "bob 3\n", + "charles 5\n", + "darwin 1\n", + "dtype: int64\n" + ] + } + ], + "source": [ + "s = pd.Series([1, 3, 5, 1, 6, 8]) # from list\n", + "print(s)\n", + "s = pd.Series([1, 3, 5, 1], index=[\"alice\", \"bob\", \"charles\", \"darwin\"]) # including index labels\n", + "print(s)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "b 1\n", + "a 0\n", + "c 2\n", + "dtype: int64" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "s = pd.Series({'b': 1, 'a': 0, 'c': 2}) #from dict\n", + "s" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Series act very similarly to a ndarray, and is a valid argument to most NumPy functions. However, operations such as slicing will also slice the index." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "b 2.718282\n", + "a 1.000000\n", + "c 7.389056\n", + "dtype: float64" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import numpy as np\n", + "np.exp(s)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "b 2\n", + "a 0\n", + "c 4\n", + "dtype: int64" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "s + s" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "b 1\n", + "a 0\n", + "dtype: int64" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "s[:2]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "A Series is also like a fixed-size dict which means you can get and set values by index label:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "s['a']" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "'b' in s" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To make it clear when you are accessing by label or by integer location, it is recommended to always use the `loc` attribute when accessing by label, and the `iloc` attribute when accessing by integer location:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "b 1\n", + "a 0\n", + "c 2\n", + "dtype: int64\n", + "accessing index label \"a\": 0\n", + "accessing integer location 1: 0\n" + ] + } + ], + "source": [ + "print(s)\n", + "print('accessing index label \"a\":', s.loc['a'])\n", + "print('accessing integer location 1:', s.iloc[1])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "When an operation involves multiple `Series` objects, `pandas` automatically aligns items by matching index labels. If some index label is not present in one of the involved `Series` the result will be `NaN` (Not-a-Number means missing), so dont forget to set the right index labels to avoid surprising results." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "b 1\n", + "a 0\n", + "c 2\n", + "dtype: int64\n", + "a 1\n", + "c 9\n", + "b 3\n", + "d 24\n", + "dtype: int64\n", + "a 1.0\n", + "b 4.0\n", + "c 11.0\n", + "d NaN\n", + "dtype: float64\n" + ] + } + ], + "source": [ + "print(s)\n", + "s2 = pd.Series({'a': 1, 'c': 9, 'b':3, 'd':24})\n", + "print(s2)\n", + "print(s + s2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## DataFrame\n", + "A DataFrame is a 2-dimensional labeled data structure with columns of potentially different types. You can think of it like a spreadsheet or SQL table, or a dict of Series objects. It is generally the most commonly used pandas object. Like Series, DataFrame accepts many different kinds of input:\n", + "* Dict of 1D arrays, lists, dicts or Series\n", + "* 2D numpy arrays\n", + "* Series\n", + "* Another DataFrame\n", + "* ...\n", + "\n", + "Along with the data, you can optionally pass **index** (row labels) and **columns** (column labels) arguments. If you pass an index and / or columns, you are guaranteeing the index and / or columns of the resulting DataFrame. Thus, a dict of Series plus a specific index will discard all data not matching up to the passed index." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "<div>\n", + "<style scoped>\n", + " .dataframe tbody tr th:only-of-type {\n", + " vertical-align: middle;\n", + " }\n", + "\n", + " .dataframe tbody tr th {\n", + " vertical-align: top;\n", + " }\n", + "\n", + " .dataframe thead th {\n", + " text-align: right;\n", + " }\n", + "</style>\n", + "<table border=\"1\" class=\"dataframe\">\n", + " <thead>\n", + " <tr style=\"text-align: right;\">\n", + " <th></th>\n", + " <th>one</th>\n", + " <th>two</th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <th>a</th>\n", + " <td>1.0</td>\n", + " <td>1.0</td>\n", + " </tr>\n", + " <tr>\n", + " <th>b</th>\n", + " <td>2.0</td>\n", + " <td>2.0</td>\n", + " </tr>\n", + " <tr>\n", + " <th>c</th>\n", + " <td>3.0</td>\n", + " <td>3.0</td>\n", + " </tr>\n", + " <tr>\n", + " <th>d</th>\n", + " <td>NaN</td>\n", + " <td>4.0</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "</div>" + ], + "text/plain": [ + " one two\n", + "a 1.0 1.0\n", + "b 2.0 2.0\n", + "c 3.0 3.0\n", + "d NaN 4.0" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df = pd.DataFrame({'one': pd.Series([1., 2., 3.], index=['a', 'b', 'c']),\n", + " 'two': pd.Series([1., 2., 3., 4.], index=['a', 'b', 'c', 'd'])})\n", + "df" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The row and column labels can be accessed respectively by accessing the **index** and **columns** attributes:" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Index(['a', 'b', 'c', 'd'], dtype='object')" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.index" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Index(['one', 'two'], dtype='object')" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.columns" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Pandas includes many functions to read a DataFrame from a variety of data formats:\n", + "* `pd.read_csv`\n", + "* `pd.read_json`\n", + "* `pd.read_sql`\n", + "* ...\n", + "\n", + "See [Pandas I/O documentation](https://pandas.pydata.org/pandas-docs/stable/reference/io.html) for more." + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [], + "source": [ + "url = \"https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data\" # download link of a csv file\n", + "names = ['sepal-length', 'sepal-width', 'petal-length', 'petal-width', 'class-label']\n", + "df = pd.read_csv(url, names=names)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Viewing data\n", + "Here is how to view the top and bottom rows of the frame:" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "<div>\n", + "<style scoped>\n", + " .dataframe tbody tr th:only-of-type {\n", + " vertical-align: middle;\n", + " }\n", + "\n", + " .dataframe tbody tr th {\n", + " vertical-align: top;\n", + " }\n", + "\n", + " .dataframe thead th {\n", + " text-align: right;\n", + " }\n", + "</style>\n", + "<table border=\"1\" class=\"dataframe\">\n", + " <thead>\n", + " <tr style=\"text-align: right;\">\n", + " <th></th>\n", + " <th>sepal-length</th>\n", + " <th>sepal-width</th>\n", + " <th>petal-length</th>\n", + " <th>petal-width</th>\n", + " <th>class-label</th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <th>0</th>\n", + " <td>5.1</td>\n", + " <td>3.5</td>\n", + " <td>1.4</td>\n", + " <td>0.2</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>1</th>\n", + " <td>4.9</td>\n", + " <td>3.0</td>\n", + " <td>1.4</td>\n", + " <td>0.2</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>2</th>\n", + " <td>4.7</td>\n", + " <td>3.2</td>\n", + " <td>1.3</td>\n", + " <td>0.2</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>3</th>\n", + " <td>4.6</td>\n", + " <td>3.1</td>\n", + " <td>1.5</td>\n", + " <td>0.2</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>4</th>\n", + " <td>5.0</td>\n", + " <td>3.6</td>\n", + " <td>1.4</td>\n", + " <td>0.2</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "</div>" + ], + "text/plain": [ + " sepal-length sepal-width petal-length petal-width class-label\n", + "0 5.1 3.5 1.4 0.2 Iris-setosa\n", + "1 4.9 3.0 1.4 0.2 Iris-setosa\n", + "2 4.7 3.2 1.3 0.2 Iris-setosa\n", + "3 4.6 3.1 1.5 0.2 Iris-setosa\n", + "4 5.0 3.6 1.4 0.2 Iris-setosa" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "<div>\n", + "<style scoped>\n", + " .dataframe tbody tr th:only-of-type {\n", + " vertical-align: middle;\n", + " }\n", + "\n", + " .dataframe tbody tr th {\n", + " vertical-align: top;\n", + " }\n", + "\n", + " .dataframe thead th {\n", + " text-align: right;\n", + " }\n", + "</style>\n", + "<table border=\"1\" class=\"dataframe\">\n", + " <thead>\n", + " <tr style=\"text-align: right;\">\n", + " <th></th>\n", + " <th>sepal-length</th>\n", + " <th>sepal-width</th>\n", + " <th>petal-length</th>\n", + " <th>petal-width</th>\n", + " <th>class-label</th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <th>145</th>\n", + " <td>6.7</td>\n", + " <td>3.0</td>\n", + " <td>5.2</td>\n", + " <td>2.3</td>\n", + " <td>Iris-virginica</td>\n", + " </tr>\n", + " <tr>\n", + " <th>146</th>\n", + " <td>6.3</td>\n", + " <td>2.5</td>\n", + " <td>5.0</td>\n", + " <td>1.9</td>\n", + " <td>Iris-virginica</td>\n", + " </tr>\n", + " <tr>\n", + " <th>147</th>\n", + " <td>6.5</td>\n", + " <td>3.0</td>\n", + " <td>5.2</td>\n", + " <td>2.0</td>\n", + " <td>Iris-virginica</td>\n", + " </tr>\n", + " <tr>\n", + " <th>148</th>\n", + " <td>6.2</td>\n", + " <td>3.4</td>\n", + " <td>5.4</td>\n", + " <td>2.3</td>\n", + " <td>Iris-virginica</td>\n", + " </tr>\n", + " <tr>\n", + " <th>149</th>\n", + " <td>5.9</td>\n", + " <td>3.0</td>\n", + " <td>5.1</td>\n", + " <td>1.8</td>\n", + " <td>Iris-virginica</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "</div>" + ], + "text/plain": [ + " sepal-length sepal-width petal-length petal-width class-label\n", + "145 6.7 3.0 5.2 2.3 Iris-virginica\n", + "146 6.3 2.5 5.0 1.9 Iris-virginica\n", + "147 6.5 3.0 5.2 2.0 Iris-virginica\n", + "148 6.2 3.4 5.4 2.3 Iris-virginica\n", + "149 5.9 3.0 5.1 1.8 Iris-virginica" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.tail()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can also take a random sample like this:" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "<div>\n", + "<style scoped>\n", + " .dataframe tbody tr th:only-of-type {\n", + " vertical-align: middle;\n", + " }\n", + "\n", + " .dataframe tbody tr th {\n", + " vertical-align: top;\n", + " }\n", + "\n", + " .dataframe thead th {\n", + " text-align: right;\n", + " }\n", + "</style>\n", + "<table border=\"1\" class=\"dataframe\">\n", + " <thead>\n", + " <tr style=\"text-align: right;\">\n", + " <th></th>\n", + " <th>sepal-length</th>\n", + " <th>sepal-width</th>\n", + " <th>petal-length</th>\n", + " <th>petal-width</th>\n", + " <th>class-label</th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <th>3</th>\n", + " <td>4.6</td>\n", + " <td>3.1</td>\n", + " <td>1.5</td>\n", + " <td>0.2</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>118</th>\n", + " <td>7.7</td>\n", + " <td>2.6</td>\n", + " <td>6.9</td>\n", + " <td>2.3</td>\n", + " <td>Iris-virginica</td>\n", + " </tr>\n", + " <tr>\n", + " <th>85</th>\n", + " <td>6.0</td>\n", + " <td>3.4</td>\n", + " <td>4.5</td>\n", + " <td>1.6</td>\n", + " <td>Iris-versicolor</td>\n", + " </tr>\n", + " <tr>\n", + " <th>103</th>\n", + " <td>6.3</td>\n", + " <td>2.9</td>\n", + " <td>5.6</td>\n", + " <td>1.8</td>\n", + " <td>Iris-virginica</td>\n", + " </tr>\n", + " <tr>\n", + " <th>108</th>\n", + " <td>6.7</td>\n", + " <td>2.5</td>\n", + " <td>5.8</td>\n", + " <td>1.8</td>\n", + " <td>Iris-virginica</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "</div>" + ], + "text/plain": [ + " sepal-length sepal-width petal-length petal-width class-label\n", + "3 4.6 3.1 1.5 0.2 Iris-setosa\n", + "118 7.7 2.6 6.9 2.3 Iris-virginica\n", + "85 6.0 3.4 4.5 1.6 Iris-versicolor\n", + "103 6.3 2.9 5.6 1.8 Iris-virginica\n", + "108 6.7 2.5 5.8 1.8 Iris-virginica" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.sample(5)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The `info` function gives you a concise summary of a DataFrame:" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "<class 'pandas.core.frame.DataFrame'>\n", + "RangeIndex: 150 entries, 0 to 149\n", + "Data columns (total 5 columns):\n", + "sepal-length 150 non-null float64\n", + "sepal-width 150 non-null float64\n", + "petal-length 150 non-null float64\n", + "petal-width 150 non-null float64\n", + "class-label 150 non-null object\n", + "dtypes: float64(4), object(1)\n", + "memory usage: 5.9+ KB\n" + ] + } + ], + "source": [ + "df.info()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Selection\n", + "Selecting a single column yields a Series:" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0 5.1\n", + "1 4.9\n", + "2 4.7\n", + "3 4.6\n", + "4 5.0\n", + "Name: sepal-length, dtype: float64" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df['sepal-length'].head()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Selecting via [], which slices the rows:" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "<div>\n", + "<style scoped>\n", + " .dataframe tbody tr th:only-of-type {\n", + " vertical-align: middle;\n", + " }\n", + "\n", + " .dataframe tbody tr th {\n", + " vertical-align: top;\n", + " }\n", + "\n", + " .dataframe thead th {\n", + " text-align: right;\n", + " }\n", + "</style>\n", + "<table border=\"1\" class=\"dataframe\">\n", + " <thead>\n", + " <tr style=\"text-align: right;\">\n", + " <th></th>\n", + " <th>sepal-length</th>\n", + " <th>sepal-width</th>\n", + " <th>petal-length</th>\n", + " <th>petal-width</th>\n", + " <th>class-label</th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <th>0</th>\n", + " <td>5.1</td>\n", + " <td>3.5</td>\n", + " <td>1.4</td>\n", + " <td>0.2</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>1</th>\n", + " <td>4.9</td>\n", + " <td>3.0</td>\n", + " <td>1.4</td>\n", + " <td>0.2</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>2</th>\n", + " <td>4.7</td>\n", + " <td>3.2</td>\n", + " <td>1.3</td>\n", + " <td>0.2</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "</div>" + ], + "text/plain": [ + " sepal-length sepal-width petal-length petal-width class-label\n", + "0 5.1 3.5 1.4 0.2 Iris-setosa\n", + "1 4.9 3.0 1.4 0.2 Iris-setosa\n", + "2 4.7 3.2 1.3 0.2 Iris-setosa" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df[0:3]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Access by label with `loc`:" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "4.9" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.loc[1,'sepal-length']" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To access entries by position, make use of `iloc`:" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "<div>\n", + "<style scoped>\n", + " .dataframe tbody tr th:only-of-type {\n", + " vertical-align: middle;\n", + " }\n", + "\n", + " .dataframe tbody tr th {\n", + " vertical-align: top;\n", + " }\n", + "\n", + " .dataframe thead th {\n", + " text-align: right;\n", + " }\n", + "</style>\n", + "<table border=\"1\" class=\"dataframe\">\n", + " <thead>\n", + " <tr style=\"text-align: right;\">\n", + " <th></th>\n", + " <th>sepal-length</th>\n", + " <th>sepal-width</th>\n", + " <th>petal-length</th>\n", + " <th>petal-width</th>\n", + " <th>class-label</th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <th>0</th>\n", + " <td>5.1</td>\n", + " <td>3.5</td>\n", + " <td>1.4</td>\n", + " <td>0.2</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>1</th>\n", + " <td>4.9</td>\n", + " <td>3.0</td>\n", + " <td>1.4</td>\n", + " <td>0.2</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>2</th>\n", + " <td>4.7</td>\n", + " <td>3.2</td>\n", + " <td>1.3</td>\n", + " <td>0.2</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "</div>" + ], + "text/plain": [ + " sepal-length sepal-width petal-length petal-width class-label\n", + "0 5.1 3.5 1.4 0.2 Iris-setosa\n", + "1 4.9 3.0 1.4 0.2 Iris-setosa\n", + "2 4.7 3.2 1.3 0.2 Iris-setosa" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.iloc[0:3]" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "<div>\n", + "<style scoped>\n", + " .dataframe tbody tr th:only-of-type {\n", + " vertical-align: middle;\n", + " }\n", + "\n", + " .dataframe tbody tr th {\n", + " vertical-align: top;\n", + " }\n", + "\n", + " .dataframe thead th {\n", + " text-align: right;\n", + " }\n", + "</style>\n", + "<table border=\"1\" class=\"dataframe\">\n", + " <thead>\n", + " <tr style=\"text-align: right;\">\n", + " <th></th>\n", + " <th>petal-width</th>\n", + " <th>class-label</th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <th>0</th>\n", + " <td>0.2</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>1</th>\n", + " <td>0.2</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>2</th>\n", + " <td>0.2</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "</div>" + ], + "text/plain": [ + " petal-width class-label\n", + "0 0.2 Iris-setosa\n", + "1 0.2 Iris-setosa\n", + "2 0.2 Iris-setosa" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.iloc[0:3, -2:]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can use Boolean Indexing to make conditional selections:" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "<div>\n", + "<style scoped>\n", + " .dataframe tbody tr th:only-of-type {\n", + " vertical-align: middle;\n", + " }\n", + "\n", + " .dataframe tbody tr th {\n", + " vertical-align: top;\n", + " }\n", + "\n", + " .dataframe thead th {\n", + " text-align: right;\n", + " }\n", + "</style>\n", + "<table border=\"1\" class=\"dataframe\">\n", + " <thead>\n", + " <tr style=\"text-align: right;\">\n", + " <th></th>\n", + " <th>sepal-length</th>\n", + " <th>sepal-width</th>\n", + " <th>petal-length</th>\n", + " <th>petal-width</th>\n", + " <th>class-label</th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <th>105</th>\n", + " <td>7.6</td>\n", + " <td>3.0</td>\n", + " <td>6.6</td>\n", + " <td>2.1</td>\n", + " <td>Iris-virginica</td>\n", + " </tr>\n", + " <tr>\n", + " <th>117</th>\n", + " <td>7.7</td>\n", + " <td>3.8</td>\n", + " <td>6.7</td>\n", + " <td>2.2</td>\n", + " <td>Iris-virginica</td>\n", + " </tr>\n", + " <tr>\n", + " <th>118</th>\n", + " <td>7.7</td>\n", + " <td>2.6</td>\n", + " <td>6.9</td>\n", + " <td>2.3</td>\n", + " <td>Iris-virginica</td>\n", + " </tr>\n", + " <tr>\n", + " <th>122</th>\n", + " <td>7.7</td>\n", + " <td>2.8</td>\n", + " <td>6.7</td>\n", + " <td>2.0</td>\n", + " <td>Iris-virginica</td>\n", + " </tr>\n", + " <tr>\n", + " <th>131</th>\n", + " <td>7.9</td>\n", + " <td>3.8</td>\n", + " <td>6.4</td>\n", + " <td>2.0</td>\n", + " <td>Iris-virginica</td>\n", + " </tr>\n", + " <tr>\n", + " <th>135</th>\n", + " <td>7.7</td>\n", + " <td>3.0</td>\n", + " <td>6.1</td>\n", + " <td>2.3</td>\n", + " <td>Iris-virginica</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "</div>" + ], + "text/plain": [ + " sepal-length sepal-width petal-length petal-width class-label\n", + "105 7.6 3.0 6.6 2.1 Iris-virginica\n", + "117 7.7 3.8 6.7 2.2 Iris-virginica\n", + "118 7.7 2.6 6.9 2.3 Iris-virginica\n", + "122 7.7 2.8 6.7 2.0 Iris-virginica\n", + "131 7.9 3.8 6.4 2.0 Iris-virginica\n", + "135 7.7 3.0 6.1 2.3 Iris-virginica" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df[df['sepal-length'] > 7.5]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "See the indexing documentation [Indexing and Selecting Data](https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#indexing) and [MultiIndex / Advanced Indexing](https://pandas.pydata.org/pandas-docs/stable/user_guide/advanced.html#advanced) for more." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## A few useful operations\n", + "\n", + "We can create a new column containing computed values like this:" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "<div>\n", + "<style scoped>\n", + " .dataframe tbody tr th:only-of-type {\n", + " vertical-align: middle;\n", + " }\n", + "\n", + " .dataframe tbody tr th {\n", + " vertical-align: top;\n", + " }\n", + "\n", + " .dataframe thead th {\n", + " text-align: right;\n", + " }\n", + "</style>\n", + "<table border=\"1\" class=\"dataframe\">\n", + " <thead>\n", + " <tr style=\"text-align: right;\">\n", + " <th></th>\n", + " <th>sepal-length</th>\n", + " <th>sepal-width</th>\n", + " <th>petal-length</th>\n", + " <th>petal-width</th>\n", + " <th>class-label</th>\n", + " <th>width-sum</th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <th>0</th>\n", + " <td>5.1</td>\n", + " <td>3.5</td>\n", + " <td>1.4</td>\n", + " <td>0.2</td>\n", + " <td>Iris-setosa</td>\n", + " <td>3.7</td>\n", + " </tr>\n", + " <tr>\n", + " <th>1</th>\n", + " <td>4.9</td>\n", + " <td>3.0</td>\n", + " <td>1.4</td>\n", + " <td>0.2</td>\n", + " <td>Iris-setosa</td>\n", + " <td>3.2</td>\n", + " </tr>\n", + " <tr>\n", + " <th>2</th>\n", + " <td>4.7</td>\n", + " <td>3.2</td>\n", + " <td>1.3</td>\n", + " <td>0.2</td>\n", + " <td>Iris-setosa</td>\n", + " <td>3.4</td>\n", + " </tr>\n", + " <tr>\n", + " <th>3</th>\n", + " <td>4.6</td>\n", + " <td>3.1</td>\n", + " <td>1.5</td>\n", + " <td>0.2</td>\n", + " <td>Iris-setosa</td>\n", + " <td>3.3</td>\n", + " </tr>\n", + " <tr>\n", + " <th>4</th>\n", + " <td>5.0</td>\n", + " <td>3.6</td>\n", + " <td>1.4</td>\n", + " <td>0.2</td>\n", + " <td>Iris-setosa</td>\n", + " <td>3.8</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "</div>" + ], + "text/plain": [ + " sepal-length sepal-width petal-length petal-width class-label \\\n", + "0 5.1 3.5 1.4 0.2 Iris-setosa \n", + "1 4.9 3.0 1.4 0.2 Iris-setosa \n", + "2 4.7 3.2 1.3 0.2 Iris-setosa \n", + "3 4.6 3.1 1.5 0.2 Iris-setosa \n", + "4 5.0 3.6 1.4 0.2 Iris-setosa \n", + "\n", + " width-sum \n", + "0 3.7 \n", + "1 3.2 \n", + "2 3.4 \n", + "3 3.3 \n", + "4 3.8 " + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df['width-sum'] = df['sepal-width'] + df['petal-width']\n", + "df.head()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can apply functions to the data using `apply`:" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "<div>\n", + "<style scoped>\n", + " .dataframe tbody tr th:only-of-type {\n", + " vertical-align: middle;\n", + " }\n", + "\n", + " .dataframe tbody tr th {\n", + " vertical-align: top;\n", + " }\n", + "\n", + " .dataframe thead th {\n", + " text-align: right;\n", + " }\n", + "</style>\n", + "<table border=\"1\" class=\"dataframe\">\n", + " <thead>\n", + " <tr style=\"text-align: right;\">\n", + " <th></th>\n", + " <th>sepal-length</th>\n", + " <th>sepal-width</th>\n", + " <th>petal-length</th>\n", + " <th>petal-width</th>\n", + " <th>class-label</th>\n", + " <th>width-sum</th>\n", + " <th>class-label-int</th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <th>74</th>\n", + " <td>6.4</td>\n", + " <td>2.9</td>\n", + " <td>4.3</td>\n", + " <td>1.3</td>\n", + " <td>Iris-versicolor</td>\n", + " <td>4.2</td>\n", + " <td>1</td>\n", + " </tr>\n", + " <tr>\n", + " <th>29</th>\n", + " <td>4.7</td>\n", + " <td>3.2</td>\n", + " <td>1.6</td>\n", + " <td>0.2</td>\n", + " <td>Iris-setosa</td>\n", + " <td>3.4</td>\n", + " <td>0</td>\n", + " </tr>\n", + " <tr>\n", + " <th>30</th>\n", + " <td>4.8</td>\n", + " <td>3.1</td>\n", + " <td>1.6</td>\n", + " <td>0.2</td>\n", + " <td>Iris-setosa</td>\n", + " <td>3.3</td>\n", + " <td>0</td>\n", + " </tr>\n", + " <tr>\n", + " <th>96</th>\n", + " <td>5.7</td>\n", + " <td>2.9</td>\n", + " <td>4.2</td>\n", + " <td>1.3</td>\n", + " <td>Iris-versicolor</td>\n", + " <td>4.2</td>\n", + " <td>1</td>\n", + " </tr>\n", + " <tr>\n", + " <th>58</th>\n", + " <td>6.6</td>\n", + " <td>2.9</td>\n", + " <td>4.6</td>\n", + " <td>1.3</td>\n", + " <td>Iris-versicolor</td>\n", + " <td>4.2</td>\n", + " <td>1</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "</div>" + ], + "text/plain": [ + " sepal-length sepal-width petal-length petal-width class-label \\\n", + "74 6.4 2.9 4.3 1.3 Iris-versicolor \n", + "29 4.7 3.2 1.6 0.2 Iris-setosa \n", + "30 4.8 3.1 1.6 0.2 Iris-setosa \n", + "96 5.7 2.9 4.2 1.3 Iris-versicolor \n", + "58 6.6 2.9 4.6 1.3 Iris-versicolor \n", + "\n", + " width-sum class-label-int \n", + "74 4.2 1 \n", + "29 3.4 0 \n", + "30 3.3 0 \n", + "96 4.2 1 \n", + "58 4.2 1 " + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def class_labels_to_int(label):\n", + " if label == 'Iris-setosa':\n", + " return 0\n", + " elif label == 'Iris-versicolor':\n", + " return 1\n", + " elif label == 'Iris-virginica':\n", + " return 2\n", + "\n", + "df['class-label-int'] = df['class-label'].apply(class_labels_to_int)\n", + "df.sample(5)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The `get_dummies` function creates a one-hot encoding for categorical columns:" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "<div>\n", + "<style scoped>\n", + " .dataframe tbody tr th:only-of-type {\n", + " vertical-align: middle;\n", + " }\n", + "\n", + " .dataframe tbody tr th {\n", + " vertical-align: top;\n", + " }\n", + "\n", + " .dataframe thead th {\n", + " text-align: right;\n", + " }\n", + "</style>\n", + "<table border=\"1\" class=\"dataframe\">\n", + " <thead>\n", + " <tr style=\"text-align: right;\">\n", + " <th></th>\n", + " <th>sepal-length</th>\n", + " <th>sepal-width</th>\n", + " <th>petal-length</th>\n", + " <th>petal-width</th>\n", + " <th>width-sum</th>\n", + " <th>class-label-int</th>\n", + " <th>class-label_Iris-setosa</th>\n", + " <th>class-label_Iris-versicolor</th>\n", + " <th>class-label_Iris-virginica</th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <th>43</th>\n", + " <td>5.0</td>\n", + " <td>3.5</td>\n", + " <td>1.6</td>\n", + " <td>0.6</td>\n", + " <td>4.1</td>\n", + " <td>0</td>\n", + " <td>1</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " </tr>\n", + " <tr>\n", + " <th>14</th>\n", + " <td>5.8</td>\n", + " <td>4.0</td>\n", + " <td>1.2</td>\n", + " <td>0.2</td>\n", + " <td>4.2</td>\n", + " <td>0</td>\n", + " <td>1</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " </tr>\n", + " <tr>\n", + " <th>35</th>\n", + " <td>5.0</td>\n", + " <td>3.2</td>\n", + " <td>1.2</td>\n", + " <td>0.2</td>\n", + " <td>3.4</td>\n", + " <td>0</td>\n", + " <td>1</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " </tr>\n", + " <tr>\n", + " <th>69</th>\n", + " <td>5.6</td>\n", + " <td>2.5</td>\n", + " <td>3.9</td>\n", + " <td>1.1</td>\n", + " <td>3.6</td>\n", + " <td>1</td>\n", + " <td>0</td>\n", + " <td>1</td>\n", + " <td>0</td>\n", + " </tr>\n", + " <tr>\n", + " <th>63</th>\n", + " <td>6.1</td>\n", + " <td>2.9</td>\n", + " <td>4.7</td>\n", + " <td>1.4</td>\n", + " <td>4.3</td>\n", + " <td>1</td>\n", + " <td>0</td>\n", + " <td>1</td>\n", + " <td>0</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "</div>" + ], + "text/plain": [ + " sepal-length sepal-width petal-length petal-width width-sum \\\n", + "43 5.0 3.5 1.6 0.6 4.1 \n", + "14 5.8 4.0 1.2 0.2 4.2 \n", + "35 5.0 3.2 1.2 0.2 3.4 \n", + "69 5.6 2.5 3.9 1.1 3.6 \n", + "63 6.1 2.9 4.7 1.4 4.3 \n", + "\n", + " class-label-int class-label_Iris-setosa class-label_Iris-versicolor \\\n", + "43 0 1 0 \n", + "14 0 1 0 \n", + "35 0 1 0 \n", + "69 1 0 1 \n", + "63 1 0 1 \n", + "\n", + " class-label_Iris-virginica \n", + "43 0 \n", + "14 0 \n", + "35 0 \n", + "69 0 \n", + "63 0 " + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pd.get_dummies(df).sample(5)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can remove columns using `drop`:" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "<div>\n", + "<style scoped>\n", + " .dataframe tbody tr th:only-of-type {\n", + " vertical-align: middle;\n", + " }\n", + "\n", + " .dataframe tbody tr th {\n", + " vertical-align: top;\n", + " }\n", + "\n", + " .dataframe thead th {\n", + " text-align: right;\n", + " }\n", + "</style>\n", + "<table border=\"1\" class=\"dataframe\">\n", + " <thead>\n", + " <tr style=\"text-align: right;\">\n", + " <th></th>\n", + " <th>sepal-length</th>\n", + " <th>sepal-width</th>\n", + " <th>petal-length</th>\n", + " <th>petal-width</th>\n", + " <th>class-label</th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <th>0</th>\n", + " <td>5.1</td>\n", + " <td>3.5</td>\n", + " <td>1.4</td>\n", + " <td>0.2</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>1</th>\n", + " <td>4.9</td>\n", + " <td>3.0</td>\n", + " <td>1.4</td>\n", + " <td>0.2</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>2</th>\n", + " <td>4.7</td>\n", + " <td>3.2</td>\n", + " <td>1.3</td>\n", + " <td>0.2</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>3</th>\n", + " <td>4.6</td>\n", + " <td>3.1</td>\n", + " <td>1.5</td>\n", + " <td>0.2</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>4</th>\n", + " <td>5.0</td>\n", + " <td>3.6</td>\n", + " <td>1.4</td>\n", + " <td>0.2</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "</div>" + ], + "text/plain": [ + " sepal-length sepal-width petal-length petal-width class-label\n", + "0 5.1 3.5 1.4 0.2 Iris-setosa\n", + "1 4.9 3.0 1.4 0.2 Iris-setosa\n", + "2 4.7 3.2 1.3 0.2 Iris-setosa\n", + "3 4.6 3.1 1.5 0.2 Iris-setosa\n", + "4 5.0 3.6 1.4 0.2 Iris-setosa" + ] + }, + "execution_count": 28, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df = df.drop(labels=['width-sum', 'class-label-int'], axis=1)\n", + "df.head()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Applying min-max normalization:" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "<div>\n", + "<style scoped>\n", + " .dataframe tbody tr th:only-of-type {\n", + " vertical-align: middle;\n", + " }\n", + "\n", + " .dataframe tbody tr th {\n", + " vertical-align: top;\n", + " }\n", + "\n", + " .dataframe thead th {\n", + " text-align: right;\n", + " }\n", + "</style>\n", + "<table border=\"1\" class=\"dataframe\">\n", + " <thead>\n", + " <tr style=\"text-align: right;\">\n", + " <th></th>\n", + " <th>sepal-length</th>\n", + " <th>sepal-width</th>\n", + " <th>petal-length</th>\n", + " <th>petal-width</th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <th>0</th>\n", + " <td>-0.206481</td>\n", + " <td>0.185833</td>\n", + " <td>-0.399774</td>\n", + " <td>-0.416111</td>\n", + " </tr>\n", + " <tr>\n", + " <th>1</th>\n", + " <td>-0.262037</td>\n", + " <td>-0.022500</td>\n", + " <td>-0.399774</td>\n", + " <td>-0.416111</td>\n", + " </tr>\n", + " <tr>\n", + " <th>2</th>\n", + " <td>-0.317593</td>\n", + " <td>0.060833</td>\n", + " <td>-0.416723</td>\n", + " <td>-0.416111</td>\n", + " </tr>\n", + " <tr>\n", + " <th>3</th>\n", + " <td>-0.345370</td>\n", + " <td>0.019167</td>\n", + " <td>-0.382825</td>\n", + " <td>-0.416111</td>\n", + " </tr>\n", + " <tr>\n", + " <th>4</th>\n", + " <td>-0.234259</td>\n", + " <td>0.227500</td>\n", + " <td>-0.399774</td>\n", + " <td>-0.416111</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "</div>" + ], + "text/plain": [ + " sepal-length sepal-width petal-length petal-width\n", + "0 -0.206481 0.185833 -0.399774 -0.416111\n", + "1 -0.262037 -0.022500 -0.399774 -0.416111\n", + "2 -0.317593 0.060833 -0.416723 -0.416111\n", + "3 -0.345370 0.019167 -0.382825 -0.416111\n", + "4 -0.234259 0.227500 -0.399774 -0.416111" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df_features = df.iloc[:, :-1]\n", + "df_norm = (df_features - df_features.mean()) / (df_features.max() - df_features.min())\n", + "df_norm.head()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Univariate descriptors\n", + "\n", + "The `describe` function computes many of the univariate descriptors for a given DataFrame, giving a nice overview of the main aggregated values over each column:\n", + "* count: number of non-null (not NaN) values\n", + "* mean: mean of non-null values\n", + "* std: standard deviation of non-null values\n", + "* min: minimum of non-null values\n", + "* 25%, 50%, 75%: 25th, 50th and 75th percentile of non-null values\n", + "* max: maximum of non-null values" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "<div>\n", + "<style scoped>\n", + " .dataframe tbody tr th:only-of-type {\n", + " vertical-align: middle;\n", + " }\n", + "\n", + " .dataframe tbody tr th {\n", + " vertical-align: top;\n", + " }\n", + "\n", + " .dataframe thead th {\n", + " text-align: right;\n", + " }\n", + "</style>\n", + "<table border=\"1\" class=\"dataframe\">\n", + " <thead>\n", + " <tr style=\"text-align: right;\">\n", + " <th></th>\n", + " <th>sepal-length</th>\n", + " <th>sepal-width</th>\n", + " <th>petal-length</th>\n", + " <th>petal-width</th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <th>count</th>\n", + " <td>150.000000</td>\n", + " <td>150.000000</td>\n", + " <td>150.000000</td>\n", + " <td>150.000000</td>\n", + " </tr>\n", + " <tr>\n", + " <th>mean</th>\n", + " <td>5.843333</td>\n", + " <td>3.054000</td>\n", + " <td>3.758667</td>\n", + " <td>1.198667</td>\n", + " </tr>\n", + " <tr>\n", + " <th>std</th>\n", + " <td>0.828066</td>\n", + " <td>0.433594</td>\n", + " <td>1.764420</td>\n", + " <td>0.763161</td>\n", + " </tr>\n", + " <tr>\n", + " <th>min</th>\n", + " <td>4.300000</td>\n", + " <td>2.000000</td>\n", + " <td>1.000000</td>\n", + " <td>0.100000</td>\n", + " </tr>\n", + " <tr>\n", + " <th>25%</th>\n", + " <td>5.100000</td>\n", + " <td>2.800000</td>\n", + " <td>1.600000</td>\n", + " <td>0.300000</td>\n", + " </tr>\n", + " <tr>\n", + " <th>50%</th>\n", + " <td>5.800000</td>\n", + " <td>3.000000</td>\n", + " <td>4.350000</td>\n", + " <td>1.300000</td>\n", + " </tr>\n", + " <tr>\n", + " <th>75%</th>\n", + " <td>6.400000</td>\n", + " <td>3.300000</td>\n", + " <td>5.100000</td>\n", + " <td>1.800000</td>\n", + " </tr>\n", + " <tr>\n", + " <th>max</th>\n", + " <td>7.900000</td>\n", + " <td>4.400000</td>\n", + " <td>6.900000</td>\n", + " <td>2.500000</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "</div>" + ], + "text/plain": [ + " sepal-length sepal-width petal-length petal-width\n", + "count 150.000000 150.000000 150.000000 150.000000\n", + "mean 5.843333 3.054000 3.758667 1.198667\n", + "std 0.828066 0.433594 1.764420 0.763161\n", + "min 4.300000 2.000000 1.000000 0.100000\n", + "25% 5.100000 2.800000 1.600000 0.300000\n", + "50% 5.800000 3.000000 4.350000 1.300000\n", + "75% 6.400000 3.300000 5.100000 1.800000\n", + "max 7.900000 4.400000 6.900000 2.500000" + ] + }, + "execution_count": 30, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.describe()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Pandas includes functions to compute data descriptors:" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "sepal-length 5.843333\n", + "sepal-width 3.054000\n", + "petal-length 3.758667\n", + "petal-width 1.198667\n", + "dtype: float64" + ] + }, + "execution_count": 31, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.mean() # mean for each column" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "sepal-length 5.80\n", + "sepal-width 3.00\n", + "petal-length 4.35\n", + "petal-width 1.30\n", + "dtype: float64" + ] + }, + "execution_count": 32, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.median() # median for each column" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0 5.0\n", + "dtype: float64" + ] + }, + "execution_count": 33, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df['sepal-length'].mode() # mode for sepal-length" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "sepal-length 0.828066\n", + "sepal-width 0.433594\n", + "petal-length 1.764420\n", + "petal-width 0.763161\n", + "dtype: float64" + ] + }, + "execution_count": 34, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.std() # std for each column" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Pandas also includes functions to visualize these descriptors.\n", + "\n", + "We can plot histograms for each feature:" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "<Figure size 432x288 with 1 Axes>" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "%matplotlib inline\n", + "df.hist(column=['sepal-length'], bins=20);" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "<Figure size 432x288 with 1 Axes>" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "df.boxplot(column=['sepal-length', 'petal-length']);" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "<Figure size 432x288 with 1 Axes>" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "df['class-label'].value_counts().plot(kind='bar');" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Bivariate descriptors\n", + "\n", + "Computing pairwise correlation coefficients (measuring linear association between two variables):" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "<div>\n", + "<style scoped>\n", + " .dataframe tbody tr th:only-of-type {\n", + " vertical-align: middle;\n", + " }\n", + "\n", + " .dataframe tbody tr th {\n", + " vertical-align: top;\n", + " }\n", + "\n", + " .dataframe thead th {\n", + " text-align: right;\n", + " }\n", + "</style>\n", + "<table border=\"1\" class=\"dataframe\">\n", + " <thead>\n", + " <tr style=\"text-align: right;\">\n", + " <th></th>\n", + " <th>sepal-length</th>\n", + " <th>sepal-width</th>\n", + " <th>petal-length</th>\n", + " <th>petal-width</th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <th>sepal-length</th>\n", + " <td>1.000000</td>\n", + " <td>-0.109369</td>\n", + " <td>0.871754</td>\n", + " <td>0.817954</td>\n", + " </tr>\n", + " <tr>\n", + " <th>sepal-width</th>\n", + " <td>-0.109369</td>\n", + " <td>1.000000</td>\n", + " <td>-0.420516</td>\n", + " <td>-0.356544</td>\n", + " </tr>\n", + " <tr>\n", + " <th>petal-length</th>\n", + " <td>0.871754</td>\n", + " <td>-0.420516</td>\n", + " <td>1.000000</td>\n", + " <td>0.962757</td>\n", + " </tr>\n", + " <tr>\n", + " <th>petal-width</th>\n", + " <td>0.817954</td>\n", + " <td>-0.356544</td>\n", + " <td>0.962757</td>\n", + " <td>1.000000</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "</div>" + ], + "text/plain": [ + " sepal-length sepal-width petal-length petal-width\n", + "sepal-length 1.000000 -0.109369 0.871754 0.817954\n", + "sepal-width -0.109369 1.000000 -0.420516 -0.356544\n", + "petal-length 0.871754 -0.420516 1.000000 0.962757\n", + "petal-width 0.817954 -0.356544 0.962757 1.000000" + ] + }, + "execution_count": 38, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.corr()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Visual inspection of correlation:" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "<Figure size 720x720 with 16 Axes>" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "pd.plotting.scatter_matrix(df, figsize=(10,10));" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For categorical features, we can use `pd.crosstab` to get the contingency table:" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "<div>\n", + "<style scoped>\n", + " .dataframe tbody tr th:only-of-type {\n", + " vertical-align: middle;\n", + " }\n", + "\n", + " .dataframe tbody tr th {\n", + " vertical-align: top;\n", + " }\n", + "\n", + " .dataframe thead th {\n", + " text-align: right;\n", + " }\n", + "</style>\n", + "<table border=\"1\" class=\"dataframe\">\n", + " <thead>\n", + " <tr style=\"text-align: right;\">\n", + " <th></th>\n", + " <th>color</th>\n", + " <th>gender</th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <th>0</th>\n", + " <td>blue</td>\n", + " <td>male</td>\n", + " </tr>\n", + " <tr>\n", + " <th>1</th>\n", + " <td>yellow</td>\n", + " <td>female</td>\n", + " </tr>\n", + " <tr>\n", + " <th>2</th>\n", + " <td>red</td>\n", + " <td>male</td>\n", + " </tr>\n", + " <tr>\n", + " <th>3</th>\n", + " <td>yellow</td>\n", + " <td>male</td>\n", + " </tr>\n", + " <tr>\n", + " <th>4</th>\n", + " <td>yellow</td>\n", + " <td>female</td>\n", + " </tr>\n", + " <tr>\n", + " <th>5</th>\n", + " <td>red</td>\n", + " <td>male</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "</div>" + ], + "text/plain": [ + " color gender\n", + "0 blue male\n", + "1 yellow female\n", + "2 red male\n", + "3 yellow male\n", + "4 yellow female\n", + "5 red male" + ] + }, + "execution_count": 40, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df = pd.DataFrame([['blue', 'male'], ['yellow', 'female'], ['red', 'male'], ['yellow', 'male'], ['yellow', 'female'], ['red', 'male']])\n", + "df.columns = ['color', 'gender']\n", + "df" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "<div>\n", + "<style scoped>\n", + " .dataframe tbody tr th:only-of-type {\n", + " vertical-align: middle;\n", + " }\n", + "\n", + " .dataframe tbody tr th {\n", + " vertical-align: top;\n", + " }\n", + "\n", + " .dataframe thead th {\n", + " text-align: right;\n", + " }\n", + "</style>\n", + "<table border=\"1\" class=\"dataframe\">\n", + " <thead>\n", + " <tr style=\"text-align: right;\">\n", + " <th>gender</th>\n", + " <th>female</th>\n", + " <th>male</th>\n", + " <th>All</th>\n", + " </tr>\n", + " <tr>\n", + " <th>color</th>\n", + " <th></th>\n", + " <th></th>\n", + " <th></th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <th>blue</th>\n", + " <td>0</td>\n", + " <td>1</td>\n", + " <td>1</td>\n", + " </tr>\n", + " <tr>\n", + " <th>red</th>\n", + " <td>0</td>\n", + " <td>2</td>\n", + " <td>2</td>\n", + " </tr>\n", + " <tr>\n", + " <th>yellow</th>\n", + " <td>2</td>\n", + " <td>1</td>\n", + " <td>3</td>\n", + " </tr>\n", + " <tr>\n", + " <th>All</th>\n", + " <td>2</td>\n", + " <td>4</td>\n", + " <td>6</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "</div>" + ], + "text/plain": [ + "gender female male All\n", + "color \n", + "blue 0 1 1\n", + "red 0 2 2\n", + "yellow 2 1 3\n", + "All 2 4 6" + ] + }, + "execution_count": 41, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pd.crosstab(df['color'], df['gender'], margins=True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Handling Missing data\n" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "<div>\n", + "<style scoped>\n", + " .dataframe tbody tr th:only-of-type {\n", + " vertical-align: middle;\n", + " }\n", + "\n", + " .dataframe tbody tr th {\n", + " vertical-align: top;\n", + " }\n", + "\n", + " .dataframe thead th {\n", + " text-align: right;\n", + " }\n", + "</style>\n", + "<table border=\"1\" class=\"dataframe\">\n", + " <thead>\n", + " <tr style=\"text-align: right;\">\n", + " <th></th>\n", + " <th>0</th>\n", + " <th>1</th>\n", + " <th>2</th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <th>0</th>\n", + " <td>1</td>\n", + " <td>2.0</td>\n", + " <td>3</td>\n", + " </tr>\n", + " <tr>\n", + " <th>1</th>\n", + " <td>4</td>\n", + " <td>NaN</td>\n", + " <td>6</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "</div>" + ], + "text/plain": [ + " 0 1 2\n", + "0 1 2.0 3\n", + "1 4 NaN 6" + ] + }, + "execution_count": 42, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df = pd.DataFrame([[1,2,3],\n", + " [4,np.nan,6]])\n", + "df" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To drop any rows that have missing data:" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "<div>\n", + "<style scoped>\n", + " .dataframe tbody tr th:only-of-type {\n", + " vertical-align: middle;\n", + " }\n", + "\n", + " .dataframe tbody tr th {\n", + " vertical-align: top;\n", + " }\n", + "\n", + " .dataframe thead th {\n", + " text-align: right;\n", + " }\n", + "</style>\n", + "<table border=\"1\" class=\"dataframe\">\n", + " <thead>\n", + " <tr style=\"text-align: right;\">\n", + " <th></th>\n", + " <th>0</th>\n", + " <th>1</th>\n", + " <th>2</th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <th>0</th>\n", + " <td>1</td>\n", + " <td>2.0</td>\n", + " <td>3</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "</div>" + ], + "text/plain": [ + " 0 1 2\n", + "0 1 2.0 3" + ] + }, + "execution_count": 43, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.dropna(how='any')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Filling missing data with a constant:" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "<div>\n", + "<style scoped>\n", + " .dataframe tbody tr th:only-of-type {\n", + " vertical-align: middle;\n", + " }\n", + "\n", + " .dataframe tbody tr th {\n", + " vertical-align: top;\n", + " }\n", + "\n", + " .dataframe thead th {\n", + " text-align: right;\n", + " }\n", + "</style>\n", + "<table border=\"1\" class=\"dataframe\">\n", + " <thead>\n", + " <tr style=\"text-align: right;\">\n", + " <th></th>\n", + " <th>0</th>\n", + " <th>1</th>\n", + " <th>2</th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <th>0</th>\n", + " <td>1</td>\n", + " <td>2.0</td>\n", + " <td>3</td>\n", + " </tr>\n", + " <tr>\n", + " <th>1</th>\n", + " <td>4</td>\n", + " <td>5.0</td>\n", + " <td>6</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "</div>" + ], + "text/plain": [ + " 0 1 2\n", + "0 1 2.0 3\n", + "1 4 5.0 6" + ] + }, + "execution_count": 44, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.fillna(value=5)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Filling missing data with column mean:" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "<div>\n", + "<style scoped>\n", + " .dataframe tbody tr th:only-of-type {\n", + " vertical-align: middle;\n", + " }\n", + "\n", + " .dataframe tbody tr th {\n", + " vertical-align: top;\n", + " }\n", + "\n", + " .dataframe thead th {\n", + " text-align: right;\n", + " }\n", + "</style>\n", + "<table border=\"1\" class=\"dataframe\">\n", + " <thead>\n", + " <tr style=\"text-align: right;\">\n", + " <th></th>\n", + " <th>0</th>\n", + " <th>1</th>\n", + " <th>2</th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <th>0</th>\n", + " <td>1</td>\n", + " <td>2.0</td>\n", + " <td>3</td>\n", + " </tr>\n", + " <tr>\n", + " <th>1</th>\n", + " <td>4</td>\n", + " <td>2.0</td>\n", + " <td>6</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "</div>" + ], + "text/plain": [ + " 0 1 2\n", + "0 1 2.0 3\n", + "1 4 2.0 6" + ] + }, + "execution_count": 45, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.fillna(df.mean())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To get the boolean mask where values are nan:" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "<div>\n", + "<style scoped>\n", + " .dataframe tbody tr th:only-of-type {\n", + " vertical-align: middle;\n", + " }\n", + "\n", + " .dataframe tbody tr th {\n", + " vertical-align: top;\n", + " }\n", + "\n", + " .dataframe thead th {\n", + " text-align: right;\n", + " }\n", + "</style>\n", + "<table border=\"1\" class=\"dataframe\">\n", + " <thead>\n", + " <tr style=\"text-align: right;\">\n", + " <th></th>\n", + " <th>0</th>\n", + " <th>1</th>\n", + " <th>2</th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <th>0</th>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " </tr>\n", + " <tr>\n", + " <th>1</th>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "</div>" + ], + "text/plain": [ + " 0 1 2\n", + "0 False False False\n", + "1 False True False" + ] + }, + "execution_count": 46, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pd.isna(df)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## What next?\n", + "\n", + "As you probably noticed by now, pandas is quite a large library with many features. Although we went through the most important features, there is still a lot to discover. Probably the best way to learn more is to get your hands dirty with some real-life data. It is also a good idea to go through pandas' excellent [documentation](http://pandas.pydata.org/pandas-docs/stable/index.html), in particular the [Cookbook](http://pandas.pydata.org/pandas-docs/stable/user_guide/cookbook.html)." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.2" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/Python_numpy_intro.ipynb b/Python_numpy_intro.ipynb new file mode 100644 index 0000000..7f3fa38 --- /dev/null +++ b/Python_numpy_intro.ipynb @@ -0,0 +1,2500 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Data Mining I - Tutorial 1\n", + "\n", + "In this first tutorial we will cover some python and numpy basics, as well as a short introduction of the Iris dataset.\n", + "\n", + "The Python and Numpy part of this tutorial is based on the jupyter notebook version of the CS231n Python + Numpy Tutorial created by Justin Johnson, which can be found [here](https://github.com/kuleshov/cs228-material/blob/master/tutorials/python/cs228-python-tutorial.ipynb)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Python" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Python is a high-level, dynamically typed multiparadigm programming language. Python code is often said to be almost like pseudocode, since it allows you to express very powerful ideas in very few lines of code while being very readable. As an example, here is an implementation of the classic quicksort algorithm in Python:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1, 1, 2, 3, 6, 8, 10]\n" + ] + } + ], + "source": [ + "def quicksort(arr):\n", + " if len(arr) <= 1:\n", + " return arr\n", + " pivot = arr[len(arr) // 2]\n", + " left = [x for x in arr if x < pivot]\n", + " middle = [x for x in arr if x == pivot]\n", + " right = [x for x in arr if x > pivot]\n", + " return quicksort(left) + middle + quicksort(right)\n", + "\n", + "print(quicksort([3,6,8,10,1,2,1]))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Python versions\n", + "There are currently two different supported versions of Python, 2 and 3. \n", + "Somewhat confusingly, Python 3 introduced many backwards-incompatible changes to the language, so code written for e.g. 2.7 may not work under 3.6 and vice versa. For this class all code will use Python >= 3.6.\n", + "\n", + "You can check your Python version at the command line by running `python --version`." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Basic data types\n", + "Like most languages, Python has a number of basic types including integers, floats, booleans, and strings. These data types behave in ways that are familiar from other programming languages.\n", + "\n", + "**Numbers**: Integers and floats work as you would expect from other languages:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "<class 'int'>\n", + "3\n", + "4\n", + "2\n", + "6\n", + "9\n", + "4\n", + "8\n", + "<class 'float'>\n", + "2.5 3.5 5.0 6.25\n" + ] + } + ], + "source": [ + "x = 3\n", + "print(type(x)) # Prints \"<class 'int'>\"\n", + "print(x) # Prints \"3\"\n", + "print(x + 1) # Addition; prints \"4\"\n", + "print(x - 1) # Subtraction; prints \"2\"\n", + "print(x * 2) # Multiplication; prints \"6\"\n", + "print(x ** 2) # Exponentiation; prints \"9\"\n", + "x += 1\n", + "print(x) # Prints \"4\"\n", + "x *= 2\n", + "print(x) # Prints \"8\"\n", + "y = 2.5\n", + "print(type(y)) # Prints \"<class 'float'>\"\n", + "print(y, y + 1, y * 2, y ** 2) # Prints \"2.5 3.5 5.0 6.25\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Note that unlike many languages, Python does not have unary increment (x++) or decrement (x--) operators.\n", + "\n", + "Python also has built-in types for long integers and complex numbers; you can find all of the details in the [documentation](https://docs.python.org/3.7/library/stdtypes.html#numeric-types-int-float-complex)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Booleans**: Python implements all of the usual operators for Boolean logic, but uses English words rather than symbols (`&&`, `||`, etc.):" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "<class 'bool'>\n", + "False\n", + "True\n", + "False\n", + "True\n" + ] + } + ], + "source": [ + "t = True\n", + "f = False\n", + "print(type(t)) # Prints \"<class 'bool'>\"\n", + "print(t and f) # Logical AND; prints \"False\"\n", + "print(t or f) # Logical OR; prints \"True\"\n", + "print(not t) # Logical NOT; prints \"False\"\n", + "print(t != f) # Logical XOR; prints \"True\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Strings**: Python has great support for strings:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "hello\n", + "5\n", + "hello world\n", + "hello world 12\n", + "hello world 12\n" + ] + } + ], + "source": [ + "hello = 'hello' # String literals can use single quotes\n", + "world = \"world\" # or double quotes; it does not matter.\n", + "print(hello) # Prints \"hello\"\n", + "print(len(hello)) # String length; prints \"5\"\n", + "hw = hello + ' ' + world # String concatenation\n", + "print(hw) # prints \"hello world\"\n", + "hw12 = '%s %s %d' % (hello, world, 12) # sprintf style string formatting\n", + "print(hw12) # prints \"hello world 12\"\n", + "hw12 = f'{hello} {world} {12}' # f-strings, a new and improved way of formatting strings, available in python >= 3.6\n", + "print(hw12)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "String objects have a bunch of useful methods; for example:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hello\n", + "HELLO\n", + " hello\n", + " hello \n", + "he(ell)(ell)o\n", + "world\n" + ] + } + ], + "source": [ + "s = \"hello\"\n", + "print(s.capitalize()) # Capitalize a string; prints \"Hello\"\n", + "print(s.upper()) # Convert a string to uppercase; prints \"HELLO\"\n", + "print(s.rjust(7)) # Right-justify a string, padding with spaces; prints \" hello\"\n", + "print(s.center(7)) # Center a string, padding with spaces; prints \" hello \"\n", + "print(s.replace('l', '(ell)')) # Replace all instances of one substring with another;\n", + " # prints \"he(ell)(ell)o\"\n", + "print(' world '.strip()) # Strip leading and trailing whitespace; prints \"world\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can find a list of all string methods in the [documentation](https://docs.python.org/3.7/library/stdtypes.html#string-methods)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Containers\n", + "Python includes several built-in container types: lists, dictionaries, sets, and tuples." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Lists\n", + "A list is the Python equivalent of an array, but is resizeable and can contain elements of different types:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[3, 1, 2] 2\n", + "2\n", + "[3, 1, 'foo']\n", + "[3, 1, 'foo', 'bar']\n", + "bar [3, 1, 'foo']\n" + ] + } + ], + "source": [ + "xs = [3, 1, 2] # Create a list\n", + "print(xs, xs[2]) # Prints \"[3, 1, 2] 2\"\n", + "print(xs[-1]) # Negative indices count from the end of the list; prints \"2\"\n", + "xs[2] = 'foo' # Lists can contain elements of different types\n", + "print(xs) # Prints \"[3, 1, 'foo']\"\n", + "xs.append('bar') # Add a new element to the end of the list\n", + "print(xs) # Prints \"[3, 1, 'foo', 'bar']\"\n", + "x = xs.pop() # Remove and return the last element of the list\n", + "print(x, xs) # Prints \"bar [3, 1, 'foo']\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "As usual, you can find all the gory details about lists in the [documentation](https://docs.python.org/3.7/tutorial/datastructures.html#more-on-lists)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Slicing**: In addition to accessing list elements one at a time, Python provides concise syntax to access sublists; this is known as slicing:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[0, 1, 2, 3, 4]\n", + "[2, 3]\n", + "[2, 3, 4]\n", + "[0, 1]\n", + "[0, 1, 2, 3, 4]\n", + "[0, 1, 2, 3]\n", + "[0, 1, 8, 9, 4]\n" + ] + } + ], + "source": [ + "nums = list(range(5)) # range is a built-in function that creates a list of integers\n", + "print(nums) # Prints \"[0, 1, 2, 3, 4]\"\n", + "print(nums[2:4]) # Get a slice from index 2 to 4 (exclusive); prints \"[2, 3]\"\n", + "print(nums[2:]) # Get a slice from index 2 to the end; prints \"[2, 3, 4]\"\n", + "print(nums[:2]) # Get a slice from the start to index 2 (exclusive); prints \"[0, 1]\"\n", + "print(nums[:]) # Get a slice of the whole list; prints \"[0, 1, 2, 3, 4]\"\n", + "print(nums[:-1]) # Slice indices can be negative; prints \"[0, 1, 2, 3]\"\n", + "nums[2:4] = [8, 9] # Assign a new sublist to a slice\n", + "print(nums) # Prints \"[0, 1, 8, 9, 4]\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We will see slicing again in the context of numpy arrays." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Loops**: You can loop over the elements of a list like this:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "cat\n", + "dog\n", + "monkey\n" + ] + } + ], + "source": [ + "animals = ['cat', 'dog', 'monkey']\n", + "for animal in animals:\n", + " print(animal)\n", + "# Prints \"cat\", \"dog\", \"monkey\", each on its own line." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If you want access to the index of each element within the body of a loop, use the built-in `enumerate` function:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "#1: cat\n", + "#2: dog\n", + "#3: monkey\n" + ] + } + ], + "source": [ + "animals = ['cat', 'dog', 'monkey']\n", + "for idx, animal in enumerate(animals):\n", + " print(f'#{idx +1}: {animal}')\n", + "# Prints \"#1: cat\", \"#2: dog\", \"#3: monkey\", each on its own line" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**List comprehensions**: When programming, frequently we want to transform one type of data into another. As a simple example, consider the following code that computes square numbers:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[0, 1, 4, 9, 16]\n" + ] + } + ], + "source": [ + "nums = [0, 1, 2, 3, 4]\n", + "squares = []\n", + "for x in nums:\n", + " squares.append(x ** 2)\n", + "print(squares) # Prints [0, 1, 4, 9, 16]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can make this code simpler using a **list comprehension**:" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[0, 1, 4, 9, 16]\n" + ] + } + ], + "source": [ + "nums = [0, 1, 2, 3, 4]\n", + "squares = [x ** 2 for x in nums]\n", + "print(squares) # Prints [0, 1, 4, 9, 16]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "List comprehensions can also contain conditions:" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[0, 4, 16]\n" + ] + } + ], + "source": [ + "nums = [0, 1, 2, 3, 4]\n", + "even_squares = [x ** 2 for x in nums if x % 2 == 0]\n", + "print(even_squares) # Prints \"[0, 4, 16]\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Dictionaries\n", + "A dictionary stores (key, value) pairs, similar to a `Map` in Java or an object in Javascript. You can use it like this:" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "cute\n", + "True\n", + "wet\n", + "N/A\n", + "wet\n", + "N/A\n" + ] + } + ], + "source": [ + "d = {'cat': 'cute', 'dog': 'furry'} # Create a new dictionary with some data\n", + "print(d['cat']) # Get an entry from a dictionary; prints \"cute\"\n", + "print('cat' in d) # Check if a dictionary has a given key; prints \"True\"\n", + "d['fish'] = 'wet' # Set an entry in a dictionary\n", + "print(d['fish']) # Prints \"wet\"\n", + "# print(d['monkey']) # KeyError: 'monkey' not a key of d\n", + "print(d.get('monkey', 'N/A')) # Get an element with a default; prints \"N/A\"\n", + "print(d.get('fish', 'N/A')) # Get an element with a default; prints \"wet\"\n", + "del d['fish'] # Remove an element from a dictionary\n", + "print(d.get('fish', 'N/A')) # \"fish\" is no longer a key; prints \"N/A\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can find all you need to know about dictionaries in the [documentation](https://docs.python.org/3.7/library/stdtypes.html#dict)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Loops**: It is easy to iterate over the keys in a dictionary:" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "A person has 2 legs\n", + "A cat has 4 legs\n", + "A spider has 8 legs\n" + ] + } + ], + "source": [ + "d = {'person': 2, 'cat': 4, 'spider': 8}\n", + "for animal in d:\n", + " legs = d[animal]\n", + " print(f'A {animal} has {legs} legs')\n", + "# Prints \"A person has 2 legs\", \"A cat has 4 legs\", \"A spider has 8 legs\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If you want access to keys and their corresponding values, use the items method:" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "A person has 2 legs\n", + "A cat has 4 legs\n", + "A spider has 8 legs\n" + ] + } + ], + "source": [ + "d = {'person': 2, 'cat': 4, 'spider': 8}\n", + "for animal, legs in d.items():\n", + " print(f'A {animal} has {legs} legs')\n", + "# Prints \"A person has 2 legs\", \"A cat has 4 legs\", \"A spider has 8 legs\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Dictionary comprehensions**: These are similar to list comprehensions, but allow you to easily construct dictionaries. For example:" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{0: 0, 2: 4, 4: 16}\n" + ] + } + ], + "source": [ + "nums = [0, 1, 2, 3, 4]\n", + "even_num_to_square = {x: x ** 2 for x in nums if x % 2 == 0}\n", + "print(even_num_to_square) # Prints \"{0: 0, 2: 4, 4: 16}\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Sets\n", + "A set is an unordered collection of distinct elements. As a simple example, consider the following:" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True\n", + "False\n", + "True\n", + "3\n", + "3\n", + "2\n" + ] + } + ], + "source": [ + "animals = {'cat', 'dog'}\n", + "print('cat' in animals) # Check if an element is in a set; prints \"True\"\n", + "print('fish' in animals) # prints \"False\"\n", + "animals.add('fish') # Add an element to a set\n", + "print('fish' in animals) # Prints \"True\"\n", + "print(len(animals)) # Number of elements in a set; prints \"3\"\n", + "animals.add('cat') # Adding an element that is already in the set does nothing\n", + "print(len(animals)) # Prints \"3\"\n", + "animals.remove('cat') # Remove an element from a set\n", + "print(len(animals)) # Prints \"2\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "As usual, everything you want to know about sets can be found in the [documentation](https://docs.python.org/3.7/library/stdtypes.html#set)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Loops**: Iterating over a set has the same syntax as iterating over a list; however since sets are unordered, you cannot make assumptions about the order in which you visit the elements of the set:" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "#1: fish\n", + "#2: cat\n", + "#3: dog\n" + ] + } + ], + "source": [ + "animals = {'cat', 'dog', 'fish'}\n", + "for idx, animal in enumerate(animals):\n", + " print(f'#{idx +1}: {animal}')\n", + "# Prints items in some undefined order" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Set comprehensions**: Like lists and dictionaries, we can easily construct sets using set comprehensions:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{0, 1, 2, 3, 4, 5}\n" + ] + } + ], + "source": [ + "from math import sqrt\n", + "nums = {int(sqrt(x)) for x in range(30)}\n", + "print(nums) # Prints \"{0, 1, 2, 3, 4, 5}\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Tuples\n", + "A tuple is an (immutable) ordered list of values. A tuple is in many ways similar to a list; one of the most important differences is that tuples can be used as keys in dictionaries and as elements of sets, while lists cannot. Here is a trivial example:" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "<class 'tuple'>\n", + "5\n", + "1\n" + ] + } + ], + "source": [ + "d = {(x, x + 1): x for x in range(10)} # Create a dictionary with tuple keys\n", + "t = (5, 6) # Create a tuple\n", + "print(type(t)) # Prints \"<class 'tuple'>\"\n", + "print(d[t]) # Prints \"5\"\n", + "print(d[(1, 2)]) # Prints \"1\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The [documentation](https://docs.python.org/3.7/tutorial/datastructures.html#tuples-and-sequences) has more information about tuples." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Functions\n", + "Python functions are defined using the `def` keyword. For example:" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "negative\n", + "zero\n", + "positive\n" + ] + } + ], + "source": [ + "def sign(x):\n", + " if x > 0:\n", + " return 'positive'\n", + " elif x < 0:\n", + " return 'negative'\n", + " else:\n", + " return 'zero'\n", + "\n", + "for x in [-1, 0, 1]:\n", + " print(sign(x))\n", + "# Prints \"negative\", \"zero\", \"positive\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We will often define functions to take optional keyword arguments, like this:" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hello, Bob\n", + "HELLO, FRED!\n" + ] + } + ], + "source": [ + "def hello(name, loud=False):\n", + " if loud:\n", + " print(f'HELLO, {name.upper()}!')\n", + " else:\n", + " print(f'Hello, {name}')\n", + "\n", + "hello('Bob') # Prints \"Hello, Bob\"\n", + "hello('Fred', loud=True) # Prints \"HELLO, FRED!\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "There is a lot more information about Python functions in the [documentation](https://docs.python.org/3.7/tutorial/controlflow.html#defining-functions)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Classes\n", + "The syntax for defining classes in Python is straightforward:" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hello, Fred\n", + "HELLO, FRED!\n" + ] + } + ], + "source": [ + "class Greeter:\n", + "\n", + " # Constructor\n", + " def __init__(self, name):\n", + " self.name = name # Create an instance variable\n", + "\n", + " # Instance method\n", + " def greet(self, loud=False):\n", + " if loud:\n", + " print(f'HELLO, {self.name.upper()}!')\n", + " else:\n", + " print(f'Hello, {self.name}')\n", + "\n", + "g = Greeter('Fred') # Construct an instance of the Greeter class\n", + "g.greet() # Call an instance method; prints \"Hello, Fred\"\n", + "g.greet(loud=True) # Call an instance method; prints \"HELLO, FRED!\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can read a lot more about Python classes in the [documentation](https://docs.python.org/3.7/tutorial/classes.html)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Numpy" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "[Numpy](http://www.numpy.org/) is the core library for scientific computing in Python. It provides a high-performance multidimensional array object, and tools for working with these arrays." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Lets import `numpy`. most people import it as `np`:" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Arrays\n", + "A numpy array is a grid of values, all of the same type, and is indexed by a tuple of nonnegative integers. The number of dimensions is the rank of the array; the shape of an array is a tuple of integers giving the size of the array along each dimension." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can initialize numpy arrays from nested Python lists, and access elements using square brackets:" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "<class 'numpy.ndarray'>\n", + "(3,)\n", + "1 2 3\n", + "[5 2 3]\n", + "(2, 3)\n", + "1 2 4\n" + ] + } + ], + "source": [ + "a = np.array([1, 2, 3]) # Create a rank 1 array\n", + "print(type(a)) # Prints \"<class 'numpy.ndarray'>\"\n", + "print(a.shape) # Prints \"(3,)\"\n", + "print(a[0], a[1], a[2]) # Prints \"1 2 3\"\n", + "a[0] = 5 # Change an element of the array\n", + "print(a) # Prints \"[5, 2, 3]\"\n", + "\n", + "b = np.array([[1,2,3],[4,5,6]]) # Create a rank 2 array\n", + "print(b.shape) # Prints \"(2, 3)\"\n", + "print(b[0, 0], b[0, 1], b[1, 0]) # Prints \"1 2 4\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Numpy also provides many functions to create arrays:" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[0. 0.]\n", + " [0. 0.]]\n", + "[[1. 1.]]\n", + "[[7 7]\n", + " [7 7]]\n", + "[[1. 0.]\n", + " [0. 1.]]\n", + "[[0.20998725 0.2464906 ]\n", + " [0.16344505 0.70387334]]\n" + ] + } + ], + "source": [ + "a = np.zeros((2,2)) # Create an array of all zeros\n", + "print(a) # Prints \"[[ 0. 0.]\n", + " # [ 0. 0.]]\"\n", + "\n", + "b = np.ones((1,2)) # Create an array of all ones\n", + "print(b) # Prints \"[[ 1. 1.]]\"\n", + "\n", + "c = np.full((2,2), 7) # Create a constant array\n", + "print(c) # Prints \"[[ 7. 7.]\n", + " # [ 7. 7.]]\"\n", + "\n", + "d = np.eye(2) # Create a 2x2 identity matrix\n", + "print(d) # Prints \"[[ 1. 0.]\n", + " # [ 0. 1.]]\"\n", + "\n", + "e = np.random.random((2,2)) # Create an array filled with random values\n", + "print(e) # Might print \"[[ 0.91940167 0.08143941]\n", + " # [ 0.68744134 0.87236687]]\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can read about other methods of array creation in the [documentation](http://docs.scipy.org/doc/numpy/user/basics.creation.html#arrays-creation)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Array Indexing\n", + "Numpy offers several ways to index into arrays." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Slicing**: Similar to Python lists, numpy arrays can be sliced. Since arrays may be multidimensional, you must specify a slice for each dimension of the array:" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2\n", + "77\n" + ] + } + ], + "source": [ + "# Create the following rank 2 array with shape (3, 4)\n", + "# [[ 1 2 3 4]\n", + "# [ 5 6 7 8]\n", + "# [ 9 10 11 12]]\n", + "a = np.array([[1,2,3,4], [5,6,7,8], [9,10,11,12]])\n", + "\n", + "# Use slicing to pull out the subarray consisting of the first 2 rows\n", + "# and columns 1 and 2; b is the following array of shape (2, 2):\n", + "# [[2 3]\n", + "# [6 7]]\n", + "b = a[:2, 1:3]\n", + "\n", + "# A slice of an array is a view into the same data, so modifying it\n", + "# will modify the original array.\n", + "print(a[0, 1]) # Prints \"2\"\n", + "b[0, 0] = 77 # b[0, 0] is the same piece of data as a[0, 1]\n", + "print(a[0, 1]) # Prints \"77\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can also mix integer indexing with slice indexing. However, doing so will yield an array of lower rank than the original array" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[5 6 7 8] (4,)\n", + "[[5 6 7 8]] (1, 4)\n", + "[ 2 6 10] (3,)\n", + "[[ 2]\n", + " [ 6]\n", + " [10]] (3, 1)\n" + ] + } + ], + "source": [ + "# Create the following rank 2 array with shape (3, 4)\n", + "# [[ 1 2 3 4]\n", + "# [ 5 6 7 8]\n", + "# [ 9 10 11 12]]\n", + "a = np.array([[1,2,3,4], [5,6,7,8], [9,10,11,12]])\n", + "\n", + "# Two ways of accessing the data in the middle row of the array.\n", + "# Mixing integer indexing with slices yields an array of lower rank,\n", + "# while using only slices yields an array of the same rank as the\n", + "# original array:\n", + "row_r1 = a[1, :] # Rank 1 view of the second row of a\n", + "row_r2 = a[1:2, :] # Rank 2 view of the second row of a\n", + "print(row_r1, row_r1.shape) # Prints \"[5 6 7 8] (4,)\"\n", + "print(row_r2, row_r2.shape) # Prints \"[[5 6 7 8]] (1, 4)\"\n", + "\n", + "# We can make the same distinction when accessing columns of an array:\n", + "col_r1 = a[:, 1]\n", + "col_r2 = a[:, 1:2]\n", + "print(col_r1, col_r1.shape) # Prints \"[ 2 6 10] (3,)\"\n", + "print(col_r2, col_r2.shape) # Prints \"[[ 2]\n", + " # [ 6]\n", + " # [10]] (3, 1)\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Integer array indexing**: When you index into numpy arrays using slicing, the resulting array view will always be a subarray of the original array. In contrast, integer array indexing allows you to construct arbitrary arrays using the data from another array. Here is an example:" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1 4 5]\n", + "[1 4 5]\n", + "[2 2]\n", + "[2 2]\n" + ] + } + ], + "source": [ + "a = np.array([[1,2], [3, 4], [5, 6]])\n", + "\n", + "# An example of integer array indexing.\n", + "# The returned array will have shape (3,) and\n", + "print(a[[0, 1, 2], [0, 1, 0]]) # Prints \"[1 4 5]\"\n", + "\n", + "# The above example of integer array indexing is equivalent to this:\n", + "print(np.array([a[0, 0], a[1, 1], a[2, 0]])) # Prints \"[1 4 5]\"\n", + "\n", + "# When using integer array indexing, you can reuse the same\n", + "# element from the source array:\n", + "print(a[[0, 0], [1, 1]]) # Prints \"[2 2]\"\n", + "\n", + "# Equivalent to the previous integer array indexing example\n", + "print(np.array([a[0, 1], a[0, 1]])) # Prints \"[2 2]\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "One useful trick with integer array indexing is selecting or mutating one element from each row of a matrix:" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[ 1 2 3]\n", + " [ 4 5 6]\n", + " [ 7 8 9]\n", + " [10 11 12]]\n", + "[ 1 6 7 11]\n", + "[[11 2 3]\n", + " [ 4 5 16]\n", + " [17 8 9]\n", + " [10 21 12]]\n" + ] + } + ], + "source": [ + "# Create a new array from which we will select elements\n", + "a = np.array([[1,2,3], [4,5,6], [7,8,9], [10, 11, 12]])\n", + "\n", + "print(a) # prints \"array([[ 1, 2, 3],\n", + " # [ 4, 5, 6],\n", + " # [ 7, 8, 9],\n", + " # [10, 11, 12]])\"\n", + "\n", + "# Create an array of indices\n", + "b = np.array([0, 2, 0, 1])\n", + "\n", + "# Select one element from each row of a using the indices in b\n", + "print(a[np.arange(4), b]) # Prints \"[ 1 6 7 11]\"\n", + "\n", + "# Mutate one element from each row of a using the indices in b\n", + "a[np.arange(4), b] += 10\n", + "\n", + "print(a) # prints \"array([[11, 2, 3],\n", + " # [ 4, 5, 16],\n", + " # [17, 8, 9],\n", + " # [10, 21, 12]])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Boolean array indexing**: Boolean array indexing lets you pick out arbitrary elements of an array. Frequently this type of indexing is used to select the elements of an array that satisfy some condition. Here is an example:" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[False False]\n", + " [ True True]\n", + " [ True True]]\n", + "[3 4 5 6]\n", + "[3 4 5 6]\n" + ] + } + ], + "source": [ + "a = np.array([[1,2], [3, 4], [5, 6]])\n", + "\n", + "bool_idx = (a > 2) # Find the elements of a that are bigger than 2;\n", + " # this returns a numpy array of Booleans of the same\n", + " # shape as a, where each slot of bool_idx tells\n", + " # whether that element of a is > 2.\n", + "\n", + "print(bool_idx) # Prints \"[[False False]\n", + " # [ True True]\n", + " # [ True True]]\"\n", + "\n", + "# We use boolean array indexing to construct a rank 1 array\n", + "# consisting of the elements of a corresponding to the True values\n", + "# of bool_idx\n", + "print(a[bool_idx]) # Prints \"[3 4 5 6]\"\n", + "\n", + "# We can do all of the above in a single concise statement:\n", + "print(a[a > 2]) # Prints \"[3 4 5 6]\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For brevity we have left out a lot of details about numpy array indexing; if you want to know more you should read the [documentation](http://docs.scipy.org/doc/numpy/reference/arrays.indexing.html)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Datatypes\n", + "Every numpy array is a grid of elements of the same type. Numpy provides a large set of numeric datatypes that you can use to construct arrays. Numpy tries to guess a datatype when you create an array, but functions that construct arrays usually also include an optional argument to explicitly specify the datatype. Here is an example:" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "int64\n", + "float64\n", + "int64\n" + ] + } + ], + "source": [ + "x = np.array([1, 2]) # Let numpy choose the datatype\n", + "print(x.dtype) # Prints \"int64\"\n", + "\n", + "x = np.array([1.0, 2.0]) # Let numpy choose the datatype\n", + "print(x.dtype) # Prints \"float64\"\n", + "\n", + "x = np.array([1, 2], dtype=np.int64) # Force a particular datatype\n", + "print(x.dtype) # Prints \"int64\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can read all about numpy datatypes in the [documentation](http://docs.scipy.org/doc/numpy/reference/arrays.dtypes.html)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Array math\n", + "Basic mathematical functions operate elementwise on arrays, and are available both as operator overloads and as functions in the numpy module:" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[ 6. 8.]\n", + " [10. 12.]]\n", + "[[ 6. 8.]\n", + " [10. 12.]]\n", + "[[-4. -4.]\n", + " [-4. -4.]]\n", + "[[-4. -4.]\n", + " [-4. -4.]]\n", + "[[ 5. 12.]\n", + " [21. 32.]]\n", + "[[ 5. 12.]\n", + " [21. 32.]]\n", + "[[0.2 0.33333333]\n", + " [0.42857143 0.5 ]]\n", + "[[0.2 0.33333333]\n", + " [0.42857143 0.5 ]]\n", + "[[1. 1.41421356]\n", + " [1.73205081 2. ]]\n" + ] + } + ], + "source": [ + "x = np.array([[1,2],[3,4]], dtype=np.float64)\n", + "y = np.array([[5,6],[7,8]], dtype=np.float64)\n", + "\n", + "# Elementwise sum; both produce the array\n", + "# [[ 6.0 8.0]\n", + "# [10.0 12.0]]\n", + "print(x + y)\n", + "print(np.add(x, y))\n", + "\n", + "# Elementwise difference; both produce the array\n", + "# [[-4.0 -4.0]\n", + "# [-4.0 -4.0]]\n", + "print(x - y)\n", + "print(np.subtract(x, y))\n", + "\n", + "# Elementwise product; both produce the array\n", + "# [[ 5.0 12.0]\n", + "# [21.0 32.0]]\n", + "print(x * y)\n", + "print(np.multiply(x, y))\n", + "\n", + "# Elementwise division; both produce the array\n", + "# [[ 0.2 0.33333333]\n", + "# [ 0.42857143 0.5 ]]\n", + "print(x / y)\n", + "print(np.divide(x, y))\n", + "\n", + "# Elementwise square root; produces the array\n", + "# [[ 1. 1.41421356]\n", + "# [ 1.73205081 2. ]]\n", + "print(np.sqrt(x))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Note that `*` is elementwise multiplication, not matrix multiplication. We instead use the `dot` function to compute inner products of vectors, to multiply a vector by a matrix, and to multiply matrices. `dot` is available both as a function in the numpy module and as an instance method of array objects:" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "219\n", + "219\n", + "[29 67]\n", + "[29 67]\n", + "[[19 22]\n", + " [43 50]]\n", + "[[19 22]\n", + " [43 50]]\n" + ] + } + ], + "source": [ + "x = np.array([[1,2],[3,4]])\n", + "y = np.array([[5,6],[7,8]])\n", + "\n", + "v = np.array([9,10])\n", + "w = np.array([11, 12])\n", + "\n", + "# Inner product of vectors; both produce 219\n", + "print(v.dot(w))\n", + "print(np.dot(v, w))\n", + "\n", + "# Matrix / vector product; both produce the rank 1 array [29 67]\n", + "print(x.dot(v))\n", + "print(np.dot(x, v))\n", + "\n", + "# Matrix / matrix product; both produce the rank 2 array\n", + "# [[19 22]\n", + "# [43 50]]\n", + "print(x.dot(y))\n", + "print(np.dot(x, y))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Numpy provides many useful functions for performing computations on arrays; one of the most useful is `sum`:" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "10\n", + "[4 6]\n", + "[3 7]\n" + ] + } + ], + "source": [ + "x = np.array([[1,2],[3,4]])\n", + "\n", + "print(np.sum(x)) # Compute sum of all elements; prints \"10\"\n", + "print(np.sum(x, axis=0)) # Compute sum of each column; prints \"[4 6]\"\n", + "print(np.sum(x, axis=1)) # Compute sum of each row; prints \"[3 7]\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can find the full list of mathematical functions provided by numpy in the [documentation](http://docs.scipy.org/doc/numpy/reference/routines.math.html)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Apart from computing mathematical functions using arrays, we frequently need to reshape or otherwise manipulate data in arrays. The simplest example of this type of operation is transposing a matrix; to transpose a matrix, simply use the `T` attribute of an array object:" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[1 2]\n", + " [3 4]]\n", + "[[1 3]\n", + " [2 4]]\n", + "[1 2 3]\n", + "[1 2 3]\n" + ] + } + ], + "source": [ + "x = np.array([[1,2], [3,4]])\n", + "print(x) # Prints \"[[1 2]\n", + " # [3 4]]\"\n", + "print(x.T) # Prints \"[[1 3]\n", + " # [2 4]]\"\n", + "\n", + "# Note that taking the transpose of a rank 1 array does nothing:\n", + "v = np.array([1,2,3])\n", + "print(v) # Prints \"[1 2 3]\"\n", + "print(v.T) # Prints \"[1 2 3]\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Numpy provides many more functions for manipulating arrays; you can see the full list in the [documentation](http://docs.scipy.org/doc/numpy/reference/routines.array-manipulation.html)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Numpy Documentation\n", + "This brief overview has touched on many of the important things that you need to know about numpy, but is far from complete. Check out the [numpy reference](http://docs.scipy.org/doc/numpy/reference/) to find out much more about numpy." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Pandas\n", + "The pandas library provides high-performance, easy-to-use data structures and data analysis tools. The main data structure is the DataFrame, which you can think of as an in-memory 2D table (like a spreadsheet, with column names and row labels). Many features available in Excel are available programmatically, such as creating pivot tables, computing columns based on other columns, plotting graphs, etc. You can also group rows by column value, or join tables much like in SQL. Pandas is also great at handling time series.\n", + "\n", + "We will have a more detailed look at pandas in the second tutorial.\n", + "\n", + "## The Iris dataset\n", + "\n", + " For now, we will use pandas to inspect our first dataset, the famous [Iris dataset](https://archive.ics.uci.edu/ml/datasets/Iris).\n" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "<div>\n", + "<style scoped>\n", + " .dataframe tbody tr th:only-of-type {\n", + " vertical-align: middle;\n", + " }\n", + "\n", + " .dataframe tbody tr th {\n", + " vertical-align: top;\n", + " }\n", + "\n", + " .dataframe thead th {\n", + " text-align: right;\n", + " }\n", + "</style>\n", + "<table border=\"1\" class=\"dataframe\">\n", + " <thead>\n", + " <tr style=\"text-align: right;\">\n", + " <th></th>\n", + " <th>sepal-length</th>\n", + " <th>sepal-width</th>\n", + " <th>petal-length</th>\n", + " <th>petal-width</th>\n", + " <th>class-label</th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <th>2</th>\n", + " <td>4.7</td>\n", + " <td>3.2</td>\n", + " <td>1.3</td>\n", + " <td>0.2</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>109</th>\n", + " <td>7.2</td>\n", + " <td>3.6</td>\n", + " <td>6.1</td>\n", + " <td>2.5</td>\n", + " <td>Iris-virginica</td>\n", + " </tr>\n", + " <tr>\n", + " <th>71</th>\n", + " <td>6.1</td>\n", + " <td>2.8</td>\n", + " <td>4.0</td>\n", + " <td>1.3</td>\n", + " <td>Iris-versicolor</td>\n", + " </tr>\n", + " <tr>\n", + " <th>144</th>\n", + " <td>6.7</td>\n", + " <td>3.3</td>\n", + " <td>5.7</td>\n", + " <td>2.5</td>\n", + " <td>Iris-virginica</td>\n", + " </tr>\n", + " <tr>\n", + " <th>128</th>\n", + " <td>6.4</td>\n", + " <td>2.8</td>\n", + " <td>5.6</td>\n", + " <td>2.1</td>\n", + " <td>Iris-virginica</td>\n", + " </tr>\n", + " <tr>\n", + " <th>26</th>\n", + " <td>5.0</td>\n", + " <td>3.4</td>\n", + " <td>1.6</td>\n", + " <td>0.4</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>75</th>\n", + " <td>6.6</td>\n", + " <td>3.0</td>\n", + " <td>4.4</td>\n", + " <td>1.4</td>\n", + " <td>Iris-versicolor</td>\n", + " </tr>\n", + " <tr>\n", + " <th>12</th>\n", + " <td>4.8</td>\n", + " <td>3.0</td>\n", + " <td>1.4</td>\n", + " <td>0.1</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>86</th>\n", + " <td>6.7</td>\n", + " <td>3.1</td>\n", + " <td>4.7</td>\n", + " <td>1.5</td>\n", + " <td>Iris-versicolor</td>\n", + " </tr>\n", + " <tr>\n", + " <th>24</th>\n", + " <td>4.8</td>\n", + " <td>3.4</td>\n", + " <td>1.9</td>\n", + " <td>0.2</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "</div>" + ], + "text/plain": [ + " sepal-length sepal-width petal-length petal-width class-label\n", + "2 4.7 3.2 1.3 0.2 Iris-setosa\n", + "109 7.2 3.6 6.1 2.5 Iris-virginica\n", + "71 6.1 2.8 4.0 1.3 Iris-versicolor\n", + "144 6.7 3.3 5.7 2.5 Iris-virginica\n", + "128 6.4 2.8 5.6 2.1 Iris-virginica\n", + "26 5.0 3.4 1.6 0.4 Iris-setosa\n", + "75 6.6 3.0 4.4 1.4 Iris-versicolor\n", + "12 4.8 3.0 1.4 0.1 Iris-setosa\n", + "86 6.7 3.1 4.7 1.5 Iris-versicolor\n", + "24 4.8 3.4 1.9 0.2 Iris-setosa" + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import pandas as pd\n", + "url = \"https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data\"\n", + "names = ['sepal-length', 'sepal-width', 'petal-length', 'petal-width', 'class-label']\n", + "dataset = pd.read_csv(url, names=names)\n", + "dataset.sample(10) # prints a ten random samples" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "`pandas` makes it easy to get an overview of the dataset and its statistics:" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "<class 'pandas.core.frame.DataFrame'>\n", + "RangeIndex: 150 entries, 0 to 149\n", + "Data columns (total 5 columns):\n", + "sepal-length 150 non-null float64\n", + "sepal-width 150 non-null float64\n", + "petal-length 150 non-null float64\n", + "petal-width 150 non-null float64\n", + "class-label 150 non-null object\n", + "dtypes: float64(4), object(1)\n", + "memory usage: 5.9+ KB\n" + ] + } + ], + "source": [ + "dataset.info()" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "<div>\n", + "<style scoped>\n", + " .dataframe tbody tr th:only-of-type {\n", + " vertical-align: middle;\n", + " }\n", + "\n", + " .dataframe tbody tr th {\n", + " vertical-align: top;\n", + " }\n", + "\n", + " .dataframe thead th {\n", + " text-align: right;\n", + " }\n", + "</style>\n", + "<table border=\"1\" class=\"dataframe\">\n", + " <thead>\n", + " <tr style=\"text-align: right;\">\n", + " <th></th>\n", + " <th>sepal-length</th>\n", + " <th>sepal-width</th>\n", + " <th>petal-length</th>\n", + " <th>petal-width</th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <th>count</th>\n", + " <td>150.000000</td>\n", + " <td>150.000000</td>\n", + " <td>150.000000</td>\n", + " <td>150.000000</td>\n", + " </tr>\n", + " <tr>\n", + " <th>mean</th>\n", + " <td>5.843333</td>\n", + " <td>3.054000</td>\n", + " <td>3.758667</td>\n", + " <td>1.198667</td>\n", + " </tr>\n", + " <tr>\n", + " <th>std</th>\n", + " <td>0.828066</td>\n", + " <td>0.433594</td>\n", + " <td>1.764420</td>\n", + " <td>0.763161</td>\n", + " </tr>\n", + " <tr>\n", + " <th>min</th>\n", + " <td>4.300000</td>\n", + " <td>2.000000</td>\n", + " <td>1.000000</td>\n", + " <td>0.100000</td>\n", + " </tr>\n", + " <tr>\n", + " <th>25%</th>\n", + " <td>5.100000</td>\n", + " <td>2.800000</td>\n", + " <td>1.600000</td>\n", + " <td>0.300000</td>\n", + " </tr>\n", + " <tr>\n", + " <th>50%</th>\n", + " <td>5.800000</td>\n", + " <td>3.000000</td>\n", + " <td>4.350000</td>\n", + " <td>1.300000</td>\n", + " </tr>\n", + " <tr>\n", + " <th>75%</th>\n", + " <td>6.400000</td>\n", + " <td>3.300000</td>\n", + " <td>5.100000</td>\n", + " <td>1.800000</td>\n", + " </tr>\n", + " <tr>\n", + " <th>max</th>\n", + " <td>7.900000</td>\n", + " <td>4.400000</td>\n", + " <td>6.900000</td>\n", + " <td>2.500000</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "</div>" + ], + "text/plain": [ + " sepal-length sepal-width petal-length petal-width\n", + "count 150.000000 150.000000 150.000000 150.000000\n", + "mean 5.843333 3.054000 3.758667 1.198667\n", + "std 0.828066 0.433594 1.764420 0.763161\n", + "min 4.300000 2.000000 1.000000 0.100000\n", + "25% 5.100000 2.800000 1.600000 0.300000\n", + "50% 5.800000 3.000000 4.350000 1.300000\n", + "75% 6.400000 3.300000 5.100000 1.800000\n", + "max 7.900000 4.400000 6.900000 2.500000" + ] + }, + "execution_count": 39, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dataset.describe()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can also filter the dataset based on features or instances quite easily:" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0 5.1\n", + "1 4.9\n", + "2 4.7\n", + "3 4.6\n", + "4 5.0\n", + "5 5.4\n", + "6 4.6\n", + "7 5.0\n", + "8 4.4\n", + "9 4.9\n", + "10 5.4\n", + "11 4.8\n", + "12 4.8\n", + "13 4.3\n", + "14 5.8\n", + "15 5.7\n", + "16 5.4\n", + "17 5.1\n", + "18 5.7\n", + "19 5.1\n", + "20 5.4\n", + "21 5.1\n", + "22 4.6\n", + "23 5.1\n", + "24 4.8\n", + "25 5.0\n", + "26 5.0\n", + "27 5.2\n", + "28 5.2\n", + "29 4.7\n", + " ... \n", + "120 6.9\n", + "121 5.6\n", + "122 7.7\n", + "123 6.3\n", + "124 6.7\n", + "125 7.2\n", + "126 6.2\n", + "127 6.1\n", + "128 6.4\n", + "129 7.2\n", + "130 7.4\n", + "131 7.9\n", + "132 6.4\n", + "133 6.3\n", + "134 6.1\n", + "135 7.7\n", + "136 6.3\n", + "137 6.4\n", + "138 6.0\n", + "139 6.9\n", + "140 6.7\n", + "141 6.9\n", + "142 5.8\n", + "143 6.8\n", + "144 6.7\n", + "145 6.7\n", + "146 6.3\n", + "147 6.5\n", + "148 6.2\n", + "149 5.9\n", + "Name: sepal-length, Length: 150, dtype: float64" + ] + }, + "execution_count": 40, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dataset['sepal-length'] # selects the 'sepal-length' feature column" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0 Iris-setosa\n", + "1 Iris-setosa\n", + "2 Iris-setosa\n", + "3 Iris-setosa\n", + "4 Iris-setosa\n", + "5 Iris-setosa\n", + "6 Iris-setosa\n", + "7 Iris-setosa\n", + "8 Iris-setosa\n", + "9 Iris-setosa\n", + "10 Iris-setosa\n", + "11 Iris-setosa\n", + "12 Iris-setosa\n", + "13 Iris-setosa\n", + "14 Iris-setosa\n", + "15 Iris-setosa\n", + "16 Iris-setosa\n", + "17 Iris-setosa\n", + "18 Iris-setosa\n", + "19 Iris-setosa\n", + "20 Iris-setosa\n", + "21 Iris-setosa\n", + "22 Iris-setosa\n", + "23 Iris-setosa\n", + "24 Iris-setosa\n", + "25 Iris-setosa\n", + "26 Iris-setosa\n", + "27 Iris-setosa\n", + "28 Iris-setosa\n", + "29 Iris-setosa\n", + " ... \n", + "120 Iris-virginica\n", + "121 Iris-virginica\n", + "122 Iris-virginica\n", + "123 Iris-virginica\n", + "124 Iris-virginica\n", + "125 Iris-virginica\n", + "126 Iris-virginica\n", + "127 Iris-virginica\n", + "128 Iris-virginica\n", + "129 Iris-virginica\n", + "130 Iris-virginica\n", + "131 Iris-virginica\n", + "132 Iris-virginica\n", + "133 Iris-virginica\n", + "134 Iris-virginica\n", + "135 Iris-virginica\n", + "136 Iris-virginica\n", + "137 Iris-virginica\n", + "138 Iris-virginica\n", + "139 Iris-virginica\n", + "140 Iris-virginica\n", + "141 Iris-virginica\n", + "142 Iris-virginica\n", + "143 Iris-virginica\n", + "144 Iris-virginica\n", + "145 Iris-virginica\n", + "146 Iris-virginica\n", + "147 Iris-virginica\n", + "148 Iris-virginica\n", + "149 Iris-virginica\n", + "Name: class-label, Length: 150, dtype: object" + ] + }, + "execution_count": 41, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dataset['class-label'] # selects the class-labels" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "<div>\n", + "<style scoped>\n", + " .dataframe tbody tr th:only-of-type {\n", + " vertical-align: middle;\n", + " }\n", + "\n", + " .dataframe tbody tr th {\n", + " vertical-align: top;\n", + " }\n", + "\n", + " .dataframe thead th {\n", + " text-align: right;\n", + " }\n", + "</style>\n", + "<table border=\"1\" class=\"dataframe\">\n", + " <thead>\n", + " <tr style=\"text-align: right;\">\n", + " <th></th>\n", + " <th>sepal-length</th>\n", + " <th>sepal-width</th>\n", + " <th>petal-length</th>\n", + " <th>petal-width</th>\n", + " <th>class-label</th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <th>0</th>\n", + " <td>5.1</td>\n", + " <td>3.5</td>\n", + " <td>1.4</td>\n", + " <td>0.2</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>1</th>\n", + " <td>4.9</td>\n", + " <td>3.0</td>\n", + " <td>1.4</td>\n", + " <td>0.2</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>2</th>\n", + " <td>4.7</td>\n", + " <td>3.2</td>\n", + " <td>1.3</td>\n", + " <td>0.2</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>3</th>\n", + " <td>4.6</td>\n", + " <td>3.1</td>\n", + " <td>1.5</td>\n", + " <td>0.2</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>4</th>\n", + " <td>5.0</td>\n", + " <td>3.6</td>\n", + " <td>1.4</td>\n", + " <td>0.2</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>5</th>\n", + " <td>5.4</td>\n", + " <td>3.9</td>\n", + " <td>1.7</td>\n", + " <td>0.4</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>6</th>\n", + " <td>4.6</td>\n", + " <td>3.4</td>\n", + " <td>1.4</td>\n", + " <td>0.3</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>7</th>\n", + " <td>5.0</td>\n", + " <td>3.4</td>\n", + " <td>1.5</td>\n", + " <td>0.2</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>8</th>\n", + " <td>4.4</td>\n", + " <td>2.9</td>\n", + " <td>1.4</td>\n", + " <td>0.2</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>9</th>\n", + " <td>4.9</td>\n", + " <td>3.1</td>\n", + " <td>1.5</td>\n", + " <td>0.1</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>10</th>\n", + " <td>5.4</td>\n", + " <td>3.7</td>\n", + " <td>1.5</td>\n", + " <td>0.2</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>11</th>\n", + " <td>4.8</td>\n", + " <td>3.4</td>\n", + " <td>1.6</td>\n", + " <td>0.2</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>12</th>\n", + " <td>4.8</td>\n", + " <td>3.0</td>\n", + " <td>1.4</td>\n", + " <td>0.1</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>13</th>\n", + " <td>4.3</td>\n", + " <td>3.0</td>\n", + " <td>1.1</td>\n", + " <td>0.1</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>14</th>\n", + " <td>5.8</td>\n", + " <td>4.0</td>\n", + " <td>1.2</td>\n", + " <td>0.2</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>15</th>\n", + " <td>5.7</td>\n", + " <td>4.4</td>\n", + " <td>1.5</td>\n", + " <td>0.4</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>16</th>\n", + " <td>5.4</td>\n", + " <td>3.9</td>\n", + " <td>1.3</td>\n", + " <td>0.4</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>17</th>\n", + " <td>5.1</td>\n", + " <td>3.5</td>\n", + " <td>1.4</td>\n", + " <td>0.3</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>18</th>\n", + " <td>5.7</td>\n", + " <td>3.8</td>\n", + " <td>1.7</td>\n", + " <td>0.3</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>19</th>\n", + " <td>5.1</td>\n", + " <td>3.8</td>\n", + " <td>1.5</td>\n", + " <td>0.3</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>20</th>\n", + " <td>5.4</td>\n", + " <td>3.4</td>\n", + " <td>1.7</td>\n", + " <td>0.2</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>21</th>\n", + " <td>5.1</td>\n", + " <td>3.7</td>\n", + " <td>1.5</td>\n", + " <td>0.4</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>22</th>\n", + " <td>4.6</td>\n", + " <td>3.6</td>\n", + " <td>1.0</td>\n", + " <td>0.2</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>23</th>\n", + " <td>5.1</td>\n", + " <td>3.3</td>\n", + " <td>1.7</td>\n", + " <td>0.5</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>24</th>\n", + " <td>4.8</td>\n", + " <td>3.4</td>\n", + " <td>1.9</td>\n", + " <td>0.2</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>25</th>\n", + " <td>5.0</td>\n", + " <td>3.0</td>\n", + " <td>1.6</td>\n", + " <td>0.2</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>26</th>\n", + " <td>5.0</td>\n", + " <td>3.4</td>\n", + " <td>1.6</td>\n", + " <td>0.4</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>27</th>\n", + " <td>5.2</td>\n", + " <td>3.5</td>\n", + " <td>1.5</td>\n", + " <td>0.2</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>28</th>\n", + " <td>5.2</td>\n", + " <td>3.4</td>\n", + " <td>1.4</td>\n", + " <td>0.2</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>29</th>\n", + " <td>4.7</td>\n", + " <td>3.2</td>\n", + " <td>1.6</td>\n", + " <td>0.2</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>30</th>\n", + " <td>4.8</td>\n", + " <td>3.1</td>\n", + " <td>1.6</td>\n", + " <td>0.2</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>31</th>\n", + " <td>5.4</td>\n", + " <td>3.4</td>\n", + " <td>1.5</td>\n", + " <td>0.4</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>32</th>\n", + " <td>5.2</td>\n", + " <td>4.1</td>\n", + " <td>1.5</td>\n", + " <td>0.1</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>33</th>\n", + " <td>5.5</td>\n", + " <td>4.2</td>\n", + " <td>1.4</td>\n", + " <td>0.2</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>34</th>\n", + " <td>4.9</td>\n", + " <td>3.1</td>\n", + " <td>1.5</td>\n", + " <td>0.1</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>35</th>\n", + " <td>5.0</td>\n", + " <td>3.2</td>\n", + " <td>1.2</td>\n", + " <td>0.2</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>36</th>\n", + " <td>5.5</td>\n", + " <td>3.5</td>\n", + " <td>1.3</td>\n", + " <td>0.2</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>37</th>\n", + " <td>4.9</td>\n", + " <td>3.1</td>\n", + " <td>1.5</td>\n", + " <td>0.1</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>38</th>\n", + " <td>4.4</td>\n", + " <td>3.0</td>\n", + " <td>1.3</td>\n", + " <td>0.2</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>39</th>\n", + " <td>5.1</td>\n", + " <td>3.4</td>\n", + " <td>1.5</td>\n", + " <td>0.2</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>40</th>\n", + " <td>5.0</td>\n", + " <td>3.5</td>\n", + " <td>1.3</td>\n", + " <td>0.3</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>41</th>\n", + " <td>4.5</td>\n", + " <td>2.3</td>\n", + " <td>1.3</td>\n", + " <td>0.3</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>42</th>\n", + " <td>4.4</td>\n", + " <td>3.2</td>\n", + " <td>1.3</td>\n", + " <td>0.2</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>43</th>\n", + " <td>5.0</td>\n", + " <td>3.5</td>\n", + " <td>1.6</td>\n", + " <td>0.6</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>44</th>\n", + " <td>5.1</td>\n", + " <td>3.8</td>\n", + " <td>1.9</td>\n", + " <td>0.4</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>45</th>\n", + " <td>4.8</td>\n", + " <td>3.0</td>\n", + " <td>1.4</td>\n", + " <td>0.3</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>46</th>\n", + " <td>5.1</td>\n", + " <td>3.8</td>\n", + " <td>1.6</td>\n", + " <td>0.2</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>47</th>\n", + " <td>4.6</td>\n", + " <td>3.2</td>\n", + " <td>1.4</td>\n", + " <td>0.2</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>48</th>\n", + " <td>5.3</td>\n", + " <td>3.7</td>\n", + " <td>1.5</td>\n", + " <td>0.2</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " <tr>\n", + " <th>49</th>\n", + " <td>5.0</td>\n", + " <td>3.3</td>\n", + " <td>1.4</td>\n", + " <td>0.2</td>\n", + " <td>Iris-setosa</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "</div>" + ], + "text/plain": [ + " sepal-length sepal-width petal-length petal-width class-label\n", + "0 5.1 3.5 1.4 0.2 Iris-setosa\n", + "1 4.9 3.0 1.4 0.2 Iris-setosa\n", + "2 4.7 3.2 1.3 0.2 Iris-setosa\n", + "3 4.6 3.1 1.5 0.2 Iris-setosa\n", + "4 5.0 3.6 1.4 0.2 Iris-setosa\n", + "5 5.4 3.9 1.7 0.4 Iris-setosa\n", + "6 4.6 3.4 1.4 0.3 Iris-setosa\n", + "7 5.0 3.4 1.5 0.2 Iris-setosa\n", + "8 4.4 2.9 1.4 0.2 Iris-setosa\n", + "9 4.9 3.1 1.5 0.1 Iris-setosa\n", + "10 5.4 3.7 1.5 0.2 Iris-setosa\n", + "11 4.8 3.4 1.6 0.2 Iris-setosa\n", + "12 4.8 3.0 1.4 0.1 Iris-setosa\n", + "13 4.3 3.0 1.1 0.1 Iris-setosa\n", + "14 5.8 4.0 1.2 0.2 Iris-setosa\n", + "15 5.7 4.4 1.5 0.4 Iris-setosa\n", + "16 5.4 3.9 1.3 0.4 Iris-setosa\n", + "17 5.1 3.5 1.4 0.3 Iris-setosa\n", + "18 5.7 3.8 1.7 0.3 Iris-setosa\n", + "19 5.1 3.8 1.5 0.3 Iris-setosa\n", + "20 5.4 3.4 1.7 0.2 Iris-setosa\n", + "21 5.1 3.7 1.5 0.4 Iris-setosa\n", + "22 4.6 3.6 1.0 0.2 Iris-setosa\n", + "23 5.1 3.3 1.7 0.5 Iris-setosa\n", + "24 4.8 3.4 1.9 0.2 Iris-setosa\n", + "25 5.0 3.0 1.6 0.2 Iris-setosa\n", + "26 5.0 3.4 1.6 0.4 Iris-setosa\n", + "27 5.2 3.5 1.5 0.2 Iris-setosa\n", + "28 5.2 3.4 1.4 0.2 Iris-setosa\n", + "29 4.7 3.2 1.6 0.2 Iris-setosa\n", + "30 4.8 3.1 1.6 0.2 Iris-setosa\n", + "31 5.4 3.4 1.5 0.4 Iris-setosa\n", + "32 5.2 4.1 1.5 0.1 Iris-setosa\n", + "33 5.5 4.2 1.4 0.2 Iris-setosa\n", + "34 4.9 3.1 1.5 0.1 Iris-setosa\n", + "35 5.0 3.2 1.2 0.2 Iris-setosa\n", + "36 5.5 3.5 1.3 0.2 Iris-setosa\n", + "37 4.9 3.1 1.5 0.1 Iris-setosa\n", + "38 4.4 3.0 1.3 0.2 Iris-setosa\n", + "39 5.1 3.4 1.5 0.2 Iris-setosa\n", + "40 5.0 3.5 1.3 0.3 Iris-setosa\n", + "41 4.5 2.3 1.3 0.3 Iris-setosa\n", + "42 4.4 3.2 1.3 0.2 Iris-setosa\n", + "43 5.0 3.5 1.6 0.6 Iris-setosa\n", + "44 5.1 3.8 1.9 0.4 Iris-setosa\n", + "45 4.8 3.0 1.4 0.3 Iris-setosa\n", + "46 5.1 3.8 1.6 0.2 Iris-setosa\n", + "47 4.6 3.2 1.4 0.2 Iris-setosa\n", + "48 5.3 3.7 1.5 0.2 Iris-setosa\n", + "49 5.0 3.3 1.4 0.2 Iris-setosa" + ] + }, + "execution_count": 42, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dataset[dataset['class-label'] == 'Iris-setosa'] # filters the dataset based on a specific class label" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Next week\n", + "We will cover more data loading, selection, manipulation, exploration and visualization next week." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.2" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} -- GitLab