From 4227518cb57ef31da9001ab9f4cbd17d2df07063 Mon Sep 17 00:00:00 2001 From: Fernando Sanz-Extremera Date: Sat, 2 Nov 2024 19:08:48 +0100 Subject: [PATCH] Solved lab v1 --- your-code/challenge-1.ipynb | 2055 +++++++++++++++++++--- your-code/challenge-2.ipynb | 3222 ++++++++++++++++++++++++++++++++--- your-code/challenge-3.ipynb | 634 +++++-- 3 files changed, 5293 insertions(+), 618 deletions(-) diff --git a/your-code/challenge-1.ipynb b/your-code/challenge-1.ipynb index cd674cb..3d29103 100644 --- a/your-code/challenge-1.ipynb +++ b/your-code/challenge-1.ipynb @@ -1,276 +1,1779 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Challenge 1\n", - "\n", - "In this challenge you will be working on **Pokemon**. You will answer a series of questions in order to practice dataframe calculation, aggregation, and transformation.\n", - "\n", - "![Pokemon](../images/pokemon.jpg)\n", - "\n", - "Follow the instructions below and enter your code.\n", - "\n", - "#### Import all required libraries." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# import libraries" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Import data set.\n", - "\n", - "Read the dataset `pokemon.csv` into a dataframe called `pokemon`.\n", - "\n", - "*Data set attributed to [Alberto Barradas](https://www.kaggle.com/abcsds/pokemon/)*" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# import dataset" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Print first 10 rows of `pokemon`." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# your code here" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "When you look at a data set, you often wonder what each column means. Some open-source data sets provide descriptions of the data set. In many cases, data descriptions are extremely useful for data analysts to perform work efficiently and successfully.\n", - "\n", - "For the `Pokemon.csv` data set, fortunately, the owner provided descriptions which you can see [here](https://www.kaggle.com/abcsds/pokemon/home). For your convenience, we are including the descriptions below. Read the descriptions and understand what each column means. This knowledge is helpful in your work with the data.\n", - "\n", - "| Column | Description |\n", - "| --- | --- |\n", - "| # | ID for each pokemon |\n", - "| Name | Name of each pokemon |\n", - "| Type 1 | Each pokemon has a type, this determines weakness/resistance to attacks |\n", - "| Type 2 | Some pokemon are dual type and have 2 |\n", - "| Total | A general guide to how strong a pokemon is |\n", - "| HP | Hit points, or health, defines how much damage a pokemon can withstand before fainting |\n", - "| Attack | The base modifier for normal attacks (eg. Scratch, Punch) |\n", - "| Defense | The base damage resistance against normal attacks |\n", - "| SP Atk | Special attack, the base modifier for special attacks (e.g. fire blast, bubble beam) |\n", - "| SP Def | The base damage resistance against special attacks |\n", - "| Speed | Determines which pokemon attacks first each round |\n", - "| Generation | Number of generation |\n", - "| Legendary | True if Legendary Pokemon False if not |" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Obtain the distinct values across `Type 1` and `Type 2`.\n", - "\n", - "Exctract all the values in `Type 1` and `Type 2`. Then create an array containing the distinct values across both fields." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# your code here" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Cleanup `Name` that contain \"Mega\".\n", - "\n", - "If you have checked out the pokemon names carefully enough, you should have found there are junk texts in the pokemon names which contain \"Mega\". We want to clean up the pokemon names. For instance, \"VenusaurMega Venusaur\" should be \"Mega Venusaur\", and \"CharizardMega Charizard X\" should be \"Mega Charizard X\"." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# your code here\n", - "\n", - "\n", - "# test transformed data\n", - "pokemon.head(10)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Create a new column called `A/D Ratio` whose value equals to `Attack` devided by `Defense`.\n", - "\n", - "For instance, if a pokemon has the Attack score 49 and Defense score 49, the corresponding `A/D Ratio` is 49/49=1." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# your code here" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Identify the pokemon with the highest `A/D Ratio`." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# your code here" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Identify the pokemon with the lowest A/D Ratio." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# your code here" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Create a new column called `Combo Type` whose value combines `Type 1` and `Type 2`.\n", - "\n", - "Rules:\n", - "\n", - "* If both `Type 1` and `Type 2` have valid values, the `Combo Type` value should contain both values in the form of ` `. For example, if `Type 1` value is `Grass` and `Type 2` value is `Poison`, `Combo Type` will be `Grass-Poison`.\n", - "\n", - "* If `Type 1` has valid value but `Type 2` is not, `Combo Type` will be the same as `Type 1`. For example, if `Type 1` is `Fire` whereas `Type 2` is `NaN`, `Combo Type` will be `Fire`." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# your code here" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Identify the pokemon whose `A/D Ratio` are among the top 5." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# your code here" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### For the 5 pokemon printed above, aggregate `Combo Type` and use a list to store the unique values.\n", - "\n", - "Your end product is a list containing the distinct `Combo Type` values of the 5 pokemon with the highest `A/D Ratio`." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# your code here" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### For each of the `Combo Type` values obtained from the previous question, calculate the mean scores of all numeric fields across all pokemon.\n", - "\n", - "Your output should look like below:\n", - "\n", - "![Aggregate](../images/aggregated-mean.png)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# your code here" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.6.9" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Challenge 1\n", + "\n", + "In this challenge you will be working on **Pokemon**. You will answer a series of questions in order to practice dataframe calculation, aggregation, and transformation.\n", + "\n", + "![Pokemon](../images/pokemon.jpg)\n", + "\n", + "Follow the instructions below and enter your code.\n", + "\n", + "#### Import all required libraries." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Import data set.\n", + "\n", + "Read the dataset `pokemon.csv` into a dataframe called `pokemon`.\n", + "\n", + "*Data set attributed to [Alberto Barradas](https://www.kaggle.com/abcsds/pokemon/)*" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "pokemon = pd.read_csv(\"pokemon.csv\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Print first 10 rows of `pokemon`." + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
#NameType 1Type 2TotalHPAttackDefenseSp. AtkSp. DefSpeedGenerationLegendary
01BulbasaurGrassPoison3184549496565451False
12IvysaurGrassPoison4056062638080601False
23VenusaurGrassPoison525808283100100801False
33VenusaurMega VenusaurGrassPoison62580100123122120801False
44CharmanderFireNaN3093952436050651False
55CharmeleonFireNaN4055864588065801False
66CharizardFireFlying534788478109851001False
76CharizardMega Charizard XFireDragon63478130111130851001False
86CharizardMega Charizard YFireFlying63478104781591151001False
97SquirtleWaterNaN3144448655064431False
\n", + "
" + ], + "text/plain": [ + " # Name Type 1 Type 2 Total HP Attack Defense \\\n", + "0 1 Bulbasaur Grass Poison 318 45 49 49 \n", + "1 2 Ivysaur Grass Poison 405 60 62 63 \n", + "2 3 Venusaur Grass Poison 525 80 82 83 \n", + "3 3 VenusaurMega Venusaur Grass Poison 625 80 100 123 \n", + "4 4 Charmander Fire NaN 309 39 52 43 \n", + "5 5 Charmeleon Fire NaN 405 58 64 58 \n", + "6 6 Charizard Fire Flying 534 78 84 78 \n", + "7 6 CharizardMega Charizard X Fire Dragon 634 78 130 111 \n", + "8 6 CharizardMega Charizard Y Fire Flying 634 78 104 78 \n", + "9 7 Squirtle Water NaN 314 44 48 65 \n", + "\n", + " Sp. Atk Sp. Def Speed Generation Legendary \n", + "0 65 65 45 1 False \n", + "1 80 80 60 1 False \n", + "2 100 100 80 1 False \n", + "3 122 120 80 1 False \n", + "4 60 50 65 1 False \n", + "5 80 65 80 1 False \n", + "6 109 85 100 1 False \n", + "7 130 85 100 1 False \n", + "8 159 115 100 1 False \n", + "9 50 64 43 1 False " + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pokemon.head(10)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "When you look at a data set, you often wonder what each column means. Some open-source data sets provide descriptions of the data set. In many cases, data descriptions are extremely useful for data analysts to perform work efficiently and successfully.\n", + "\n", + "For the `Pokemon.csv` data set, fortunately, the owner provided descriptions which you can see [here](https://www.kaggle.com/abcsds/pokemon/home). For your convenience, we are including the descriptions below. Read the descriptions and understand what each column means. This knowledge is helpful in your work with the data.\n", + "\n", + "| Column | Description |\n", + "| --- | --- |\n", + "| # | ID for each pokemon |\n", + "| Name | Name of each pokemon |\n", + "| Type 1 | Each pokemon has a type, this determines weakness/resistance to attacks |\n", + "| Type 2 | Some pokemon are dual type and have 2 |\n", + "| Total | A general guide to how strong a pokemon is |\n", + "| HP | Hit points, or health, defines how much damage a pokemon can withstand before fainting |\n", + "| Attack | The base modifier for normal attacks (eg. Scratch, Punch) |\n", + "| Defense | The base damage resistance against normal attacks |\n", + "| SP Atk | Special attack, the base modifier for special attacks (e.g. fire blast, bubble beam) |\n", + "| SP Def | The base damage resistance against special attacks |\n", + "| Speed | Determines which pokemon attacks first each round |\n", + "| Generation | Number of generation |\n", + "| Legendary | True if Legendary Pokemon False if not |" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Obtain the distinct values across `Type 1` and `Type 2`.\n", + "\n", + "Exctract all the values in `Type 1` and `Type 2`. Then create an array containing the distinct values across both fields." + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['Fairy',\n", + " 'Fighting',\n", + " 'Ice',\n", + " 'Dragon',\n", + " nan,\n", + " 'Grass',\n", + " 'Ghost',\n", + " 'Psychic',\n", + " 'Dark',\n", + " 'Fire',\n", + " 'Normal',\n", + " 'Flying',\n", + " 'Rock',\n", + " 'Electric',\n", + " 'Water',\n", + " 'Poison',\n", + " 'Steel',\n", + " 'Bug',\n", + " 'Ground']" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "all_values = list(set(list(pokemon[\"Type 1\"])+list(pokemon[\"Type 2\"])))\n", + "all_values" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Cleanup `Name` that contain \"Mega\".\n", + "\n", + "If you have checked out the pokemon names carefully enough, you should have found there are junk texts in the pokemon names which contain \"Mega\". We want to clean up the pokemon names. For instance, \"VenusaurMega Venusaur\" should be \"Mega Venusaur\", and \"CharizardMega Charizard X\" should be \"Mega Charizard X\"." + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
#NameType 1Type 2TotalHPAttackDefenseSp. AtkSp. DefSpeedGenerationLegendary
01BulbasaurGrassPoison3184549496565451False
12IvysaurGrassPoison4056062638080601False
23VenusaurGrassPoison525808283100100801False
33Mega VenusaurGrassPoison62580100123122120801False
44CharmanderFireNaN3093952436050651False
55CharmeleonFireNaN4055864588065801False
66CharizardFireFlying534788478109851001False
76Mega Charizard XFireDragon63478130111130851001False
86Mega Charizard YFireFlying63478104781591151001False
97SquirtleWaterNaN3144448655064431False
\n", + "
" + ], + "text/plain": [ + " # Name Type 1 Type 2 Total HP Attack Defense Sp. Atk \\\n", + "0 1 Bulbasaur Grass Poison 318 45 49 49 65 \n", + "1 2 Ivysaur Grass Poison 405 60 62 63 80 \n", + "2 3 Venusaur Grass Poison 525 80 82 83 100 \n", + "3 3 Mega Venusaur Grass Poison 625 80 100 123 122 \n", + "4 4 Charmander Fire NaN 309 39 52 43 60 \n", + "5 5 Charmeleon Fire NaN 405 58 64 58 80 \n", + "6 6 Charizard Fire Flying 534 78 84 78 109 \n", + "7 6 Mega Charizard X Fire Dragon 634 78 130 111 130 \n", + "8 6 Mega Charizard Y Fire Flying 634 78 104 78 159 \n", + "9 7 Squirtle Water NaN 314 44 48 65 50 \n", + "\n", + " Sp. Def Speed Generation Legendary \n", + "0 65 45 1 False \n", + "1 80 60 1 False \n", + "2 100 80 1 False \n", + "3 120 80 1 False \n", + "4 50 65 1 False \n", + "5 65 80 1 False \n", + "6 85 100 1 False \n", + "7 85 100 1 False \n", + "8 115 100 1 False \n", + "9 64 43 1 False " + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# your code here\n", + "pokemon[\"Name\"] = pokemon[\"Name\"].str.replace(\".*Mega\", \"Mega\", regex=True)\n", + "\n", + "# test transformed data\n", + "pokemon.head(10)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Create a new column called `A/D Ratio` whose value equals to `Attack` devided by `Defense`.\n", + "\n", + "For instance, if a pokemon has the Attack score 49 and Defense score 49, the corresponding `A/D Ratio` is 49/49=1." + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
#NameType 1Type 2TotalHPAttackDefenseSp. AtkSp. DefSpeedGenerationLegendaryA/D Ratio
01BulbasaurGrassPoison3184549496565451False1.00
12IvysaurGrassPoison4056062638080601False0.98
23VenusaurGrassPoison525808283100100801False0.99
33Mega VenusaurGrassPoison62580100123122120801False0.81
44CharmanderFireNaN3093952436050651False1.21
.............................................
795719DiancieRockFairy60050100150100150506True0.67
796719Mega DiancieRockFairy700501601101601101106True1.45
797720HoopaHoopa ConfinedPsychicGhost6008011060150130706True1.83
798720HoopaHoopa UnboundPsychicDark6808016060170130806True2.67
799721VolcanionFireWater6008011012013090706True0.92
\n", + "

800 rows × 14 columns

\n", + "
" + ], + "text/plain": [ + " # Name Type 1 Type 2 Total HP Attack Defense \\\n", + "0 1 Bulbasaur Grass Poison 318 45 49 49 \n", + "1 2 Ivysaur Grass Poison 405 60 62 63 \n", + "2 3 Venusaur Grass Poison 525 80 82 83 \n", + "3 3 Mega Venusaur Grass Poison 625 80 100 123 \n", + "4 4 Charmander Fire NaN 309 39 52 43 \n", + ".. ... ... ... ... ... .. ... ... \n", + "795 719 Diancie Rock Fairy 600 50 100 150 \n", + "796 719 Mega Diancie Rock Fairy 700 50 160 110 \n", + "797 720 HoopaHoopa Confined Psychic Ghost 600 80 110 60 \n", + "798 720 HoopaHoopa Unbound Psychic Dark 680 80 160 60 \n", + "799 721 Volcanion Fire Water 600 80 110 120 \n", + "\n", + " Sp. Atk Sp. Def Speed Generation Legendary A/D Ratio \n", + "0 65 65 45 1 False 1.00 \n", + "1 80 80 60 1 False 0.98 \n", + "2 100 100 80 1 False 0.99 \n", + "3 122 120 80 1 False 0.81 \n", + "4 60 50 65 1 False 1.21 \n", + ".. ... ... ... ... ... ... \n", + "795 100 150 50 6 True 0.67 \n", + "796 160 110 110 6 True 1.45 \n", + "797 150 130 70 6 True 1.83 \n", + "798 170 130 80 6 True 2.67 \n", + "799 130 90 70 6 True 0.92 \n", + "\n", + "[800 rows x 14 columns]" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pokemon[\"A/D Ratio\"] = round(pokemon[\"Attack\"] / pokemon[\"Defense\"], 2)\n", + "pokemon" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Identify the pokemon with the highest `A/D Ratio`." + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
#NameType 1Type 2TotalHPAttackDefenseSp. AtkSp. DefSpeedGenerationLegendaryA/D Ratio
429386DeoxysAttack FormePsychicNaN6005018020180201503True9.0
\n", + "
" + ], + "text/plain": [ + " # Name Type 1 Type 2 Total HP Attack Defense \\\n", + "429 386 DeoxysAttack Forme Psychic NaN 600 50 180 20 \n", + "\n", + " Sp. Atk Sp. Def Speed Generation Legendary A/D Ratio \n", + "429 180 20 150 3 True 9.0 " + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pokemon.sort_values(by =\"A/D Ratio\", ascending=False).head(1)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Identify the pokemon with the lowest A/D Ratio." + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
#NameType 1Type 2TotalHPAttackDefenseSp. AtkSp. DefSpeedGenerationLegendaryA/D Ratio
230213ShuckleBugRock50520102301023052False0.04
\n", + "
" + ], + "text/plain": [ + " # Name Type 1 Type 2 Total HP Attack Defense Sp. Atk Sp. Def \\\n", + "230 213 Shuckle Bug Rock 505 20 10 230 10 230 \n", + "\n", + " Speed Generation Legendary A/D Ratio \n", + "230 5 2 False 0.04 " + ] + }, + "execution_count": 28, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pokemon.sort_values(by =\"A/D Ratio\", ascending=True).head(1)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Create a new column called `Combo Type` whose value combines `Type 1` and `Type 2`.\n", + "\n", + "Rules:\n", + "\n", + "* If both `Type 1` and `Type 2` have valid values, the `Combo Type` value should contain both values in the form of ` `. For example, if `Type 1` value is `Grass` and `Type 2` value is `Poison`, `Combo Type` will be `Grass-Poison`.\n", + "\n", + "* If `Type 1` has valid value but `Type 2` is not, `Combo Type` will be the same as `Type 1`. For example, if `Type 1` is `Fire` whereas `Type 2` is `NaN`, `Combo Type` will be `Fire`." + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "C:\\Users\\FernandoSanz-Extreme\\AppData\\Local\\Temp\\ipykernel_9944\\326325760.py:2: FutureWarning: A value is trying to be set on a copy of a DataFrame or Series through chained assignment using an inplace method.\n", + "The behavior will change in pandas 3.0. This inplace method will never work because the intermediate object on which we are setting values always behaves as a copy.\n", + "\n", + "For example, when doing 'df[col].method(value, inplace=True)', try using 'df.method({col: value}, inplace=True)' or df[col] = df[col].method(value) instead, to perform the operation inplace on the original object.\n", + "\n", + "\n", + " pokemon[\"Combo Type\"].fillna(pokemon[\"Type 1\"], inplace=True)\n" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
#NameType 1Type 2TotalHPAttackDefenseSp. AtkSp. DefSpeedGenerationLegendaryA/D RatioCombo Type
01BulbasaurGrassPoison3184549496565451False1.00Grass-Poison
12IvysaurGrassPoison4056062638080601False0.98Grass-Poison
23VenusaurGrassPoison525808283100100801False0.99Grass-Poison
33Mega VenusaurGrassPoison62580100123122120801False0.81Grass-Poison
44CharmanderFireNaN3093952436050651False1.21Fire
................................................
795719DiancieRockFairy60050100150100150506True0.67Rock-Fairy
796719Mega DiancieRockFairy700501601101601101106True1.45Rock-Fairy
797720HoopaHoopa ConfinedPsychicGhost6008011060150130706True1.83Psychic-Ghost
798720HoopaHoopa UnboundPsychicDark6808016060170130806True2.67Psychic-Dark
799721VolcanionFireWater6008011012013090706True0.92Fire-Water
\n", + "

800 rows × 15 columns

\n", + "
" + ], + "text/plain": [ + " # Name Type 1 Type 2 Total HP Attack Defense \\\n", + "0 1 Bulbasaur Grass Poison 318 45 49 49 \n", + "1 2 Ivysaur Grass Poison 405 60 62 63 \n", + "2 3 Venusaur Grass Poison 525 80 82 83 \n", + "3 3 Mega Venusaur Grass Poison 625 80 100 123 \n", + "4 4 Charmander Fire NaN 309 39 52 43 \n", + ".. ... ... ... ... ... .. ... ... \n", + "795 719 Diancie Rock Fairy 600 50 100 150 \n", + "796 719 Mega Diancie Rock Fairy 700 50 160 110 \n", + "797 720 HoopaHoopa Confined Psychic Ghost 600 80 110 60 \n", + "798 720 HoopaHoopa Unbound Psychic Dark 680 80 160 60 \n", + "799 721 Volcanion Fire Water 600 80 110 120 \n", + "\n", + " Sp. Atk Sp. Def Speed Generation Legendary A/D Ratio Combo Type \n", + "0 65 65 45 1 False 1.00 Grass-Poison \n", + "1 80 80 60 1 False 0.98 Grass-Poison \n", + "2 100 100 80 1 False 0.99 Grass-Poison \n", + "3 122 120 80 1 False 0.81 Grass-Poison \n", + "4 60 50 65 1 False 1.21 Fire \n", + ".. ... ... ... ... ... ... ... \n", + "795 100 150 50 6 True 0.67 Rock-Fairy \n", + "796 160 110 110 6 True 1.45 Rock-Fairy \n", + "797 150 130 70 6 True 1.83 Psychic-Ghost \n", + "798 170 130 80 6 True 2.67 Psychic-Dark \n", + "799 130 90 70 6 True 0.92 Fire-Water \n", + "\n", + "[800 rows x 15 columns]" + ] + }, + "execution_count": 30, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pokemon[\"Combo Type\"] = pokemon[\"Type 1\"] + \"-\" + pokemon[\"Type 2\"]\n", + "pokemon[\"Combo Type\"].fillna(pokemon[\"Type 1\"], inplace=True)\n", + "pokemon" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Identify the pokemon whose `A/D Ratio` are among the top 5." + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
#NameType 1Type 2TotalHPAttackDefenseSp. AtkSp. DefSpeedGenerationLegendaryA/D RatioCombo Type
429386DeoxysAttack FormePsychicNaN6005018020180201503True9.00Psychic
347318CarvanhaWaterDark3054590206520653False4.50Water-Dark
1915Mega BeedrillBugPoison495651504015801451False3.75Bug-Poison
453408CranidosRockNaN35067125403030584False3.12Rock
348319SharpedoWaterDark46070120409540953False3.00Water-Dark
\n", + "
" + ], + "text/plain": [ + " # Name Type 1 Type 2 Total HP Attack Defense \\\n", + "429 386 DeoxysAttack Forme Psychic NaN 600 50 180 20 \n", + "347 318 Carvanha Water Dark 305 45 90 20 \n", + "19 15 Mega Beedrill Bug Poison 495 65 150 40 \n", + "453 408 Cranidos Rock NaN 350 67 125 40 \n", + "348 319 Sharpedo Water Dark 460 70 120 40 \n", + "\n", + " Sp. Atk Sp. Def Speed Generation Legendary A/D Ratio Combo Type \n", + "429 180 20 150 3 True 9.00 Psychic \n", + "347 65 20 65 3 False 4.50 Water-Dark \n", + "19 15 80 145 1 False 3.75 Bug-Poison \n", + "453 30 30 58 4 False 3.12 Rock \n", + "348 95 40 95 3 False 3.00 Water-Dark " + ] + }, + "execution_count": 31, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pokemon.sort_values(by =\"A/D Ratio\", ascending=False).head(5)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### For the 5 pokemon printed above, aggregate `Combo Type` and use a list to store the unique values.\n", + "\n", + "Your end product is a list containing the distinct `Combo Type` values of the 5 pokemon with the highest `A/D Ratio`." + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": {}, + "outputs": [], + "source": [ + "top5 = pokemon.sort_values(by =\"A/D Ratio\", ascending=False).head(5).reset_index()" + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['Rock', 'Water-Dark', 'Bug-Poison', 'Psychic']" + ] + }, + "execution_count": 48, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "combo_list = list(set(top5[\"Combo Type\"]))\n", + "combo_list\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### For each of the `Combo Type` values obtained from the previous question, calculate the mean scores of all numeric fields across all pokemon.\n", + "\n", + "Your output should look like below:\n", + "\n", + "![Aggregate](../images/aggregated-mean.png)" + ] + }, + { + "cell_type": "code", + "execution_count": 68, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
#TotalHPAttackDefenseSp. AtkSp. DefSpeedGenerationLegendaryA/D Ratio
Combo Type
Bug-Poison199.166667347.91666753.75000068.33333358.08333342.50000059.33333365.9166672.3333330.0000001.315833
Psychic381.973684464.55263272.55263264.94736867.23684298.55263282.39473778.8684213.3421050.2368421.164211
Rock410.111111409.44444467.111111103.333333107.22222240.55555658.33333332.8888893.8888890.1111111.258889
Water-Dark347.666667493.83333369.166667120.00000065.16666788.83333363.50000087.1666673.1666670.0000002.291667
\n", + "
" + ], + "text/plain": [ + " # Total HP Attack Defense \\\n", + "Combo Type \n", + "Bug-Poison 199.166667 347.916667 53.750000 68.333333 58.083333 \n", + "Psychic 381.973684 464.552632 72.552632 64.947368 67.236842 \n", + "Rock 410.111111 409.444444 67.111111 103.333333 107.222222 \n", + "Water-Dark 347.666667 493.833333 69.166667 120.000000 65.166667 \n", + "\n", + " Sp. Atk Sp. Def Speed Generation Legendary A/D Ratio \n", + "Combo Type \n", + "Bug-Poison 42.500000 59.333333 65.916667 2.333333 0.000000 1.315833 \n", + "Psychic 98.552632 82.394737 78.868421 3.342105 0.236842 1.164211 \n", + "Rock 40.555556 58.333333 32.888889 3.888889 0.111111 1.258889 \n", + "Water-Dark 88.833333 63.500000 87.166667 3.166667 0.000000 2.291667 " + ] + }, + "execution_count": 68, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pokemon2 = pokemon[pokemon[\"Combo Type\"].isin(combo_list)]\n", + "pivot = pokemon2.pivot_table(index=\"Combo Type\", values=['#', 'Total', 'HP', 'Attack', 'Defense', 'Sp. Atk', 'Sp. Def', 'Speed', 'Generation', 'Legendary', 'A/D Ratio'], aggfunc=\"mean\")\n", + "pivot[['#', 'Total', 'HP', 'Attack', 'Defense', 'Sp. Atk', 'Sp. Def', 'Speed', 'Generation', 'Legendary', 'A/D Ratio']]" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "base", + "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.12.4" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/your-code/challenge-2.ipynb b/your-code/challenge-2.ipynb index d347731..3490fbb 100644 --- a/your-code/challenge-2.ipynb +++ b/your-code/challenge-2.ipynb @@ -1,195 +1,3027 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Challenge 2\n", - "\n", - "In this challenge we will continue working with the `Pokemon` dataset. We will attempt solving a slightly more complex problem in which we will practice the iterative data analysis process you leaned in [this video](https://www.youtube.com/watch?v=xOomNicqbkk).\n", - "\n", - "The problem statement is as follows:\n", - "\n", - "**You are at a Pokemon black market planning to buy a Pokemon for battle. All Pokemon are sold at the same price and you can only afford to buy one. You cannot choose which specific Pokemon to buy. However, you can specify the type of the Pokemon - one type that exists in either `Type 1` or `Type 2`. Which type should you choose in order to maximize your chance of receiving a good Pokemon?**\n", - "\n", - "To remind you about the 3 steps of iterative data analysis, they are:\n", - "\n", - "1. Setting Expectations\n", - "1. Collecting Information\n", - "1. Reacting to Data / Revising Expectations\n", - "\n", - "Following the iterative process, we'll guide you in completing the challenge." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - "## Problem Solving Iteration 1\n", - "\n", - "In this iteration we'll analyze the problem and identify the breakthrough. The original question statement is kind of vague because we don't know what a *good pokemon* really means as represented in the data. We'll start by understanding the dataset and see if we can find some insights." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Import libraries\n", - "import numpy as np\n", - "import pandas as pd" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "scrolled": true - }, - "outputs": [], - "source": [ - "# Importing the dataset" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "From the data it seems whether a pokemon is good depends on its abilities as represented in the fields of `HP`, `Attack`, `Defense`, `Sp. Atk`, `Sp. Def`, `Speed`, and `Total`. We are not sure about `Generation` and `Legendary` because they are not necessarily the decisive factors of the pokemon abilities.\n", - "\n", - "But `HP`, `Attack`, `Defense`, `Sp. Atk`, `Sp. Def`, `Speed`, and `Total` are a lot of fields! If we look at them all at once it's very complicated. This isn't Mission Impossible but it's ideal that we tackle this kind of problem after we learn Machine Learning (which you will do in Module 3). For now, is there a way to consolidate the fields we need to look into?\n", - "\n", - "Fortunately there seems to be a way. It appears the `Total` field is computed based on the other 6 fields. But we need to prove our theory. If we can approve there is a formula to compute `Total` based on the other 6 abilities, we only need to look into `Total`.\n", - "\n", - "We have the following expectation now:\n", - "\n", - "#### The `Total` field is computed based on `HP`, `Attack`, `Defense`, `Sp. Atk`, `Sp. Def`, and `Speed`.\n", - "\n", - "We need to collect the following information:\n", - "\n", - "* **What is the formula to compute `Total`?**\n", - "* **Does the formula work for all pokemon?**\n", - "\n", - "In the cell below, make a hypothesis on how `Total` is computed and test your hypothesis." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# your code here" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Problem Solving Iteration 2\n", - "\n", - "Now that we have consolidated the abilities fields, we can update the problem statement. The new problem statement is:\n", - "\n", - "### Which pokemon type is most likely to have the highest `Total` value?\n", - "\n", - "In the updated problem statement, we assume there is a certain relationship between the `Total` and the pokemon type. But we have two *type* fields (`Type 1` and `Type 2`) that have string values. In data analysis, string fields have to be transformed to numerical format in order to be analyzed. \n", - "\n", - "In addition, keep in mind that `Type 1` always has a value but `Type 2` is sometimes empty (having the `NaN` value). Also, the pokemon type we choose may be either in `Type 1` or `Type 2`.\n", - "\n", - "Now our expectation is:\n", - "\n", - "#### `Type 1` and `Type 2` string variables need to be converted to numerical variables in order to identify the relationship between `Total` and the pokemon type.\n", - "\n", - "The information we need to collect is:\n", - "\n", - "#### How to convert two string variables to numerical?\n", - "\n", - "Let's address the first question first. You can use a method called **One Hot Encoding** which is frequently used in machine learning to encode categorical string variables to numerical. The idea is to gather all the possible string values in a categorical field and create a numerical field for each unique string value. Each of those numerical fields uses `1` and `0` to indicate whether the data record has the corresponding categorical value. A detailed explanation of One Hot Encoding can be found in [this article](https://hackernoon.com/what-is-one-hot-encoding-why-and-when-do-you-have-to-use-it-e3c6186d008f). You will formally learn it in Module 3.\n", - "\n", - "For instance, if a pokemon has `Type 1` as `Poison` and `Type 2` as `Fire`, then its `Poison` and `Fire` fields are `1` whereas all other fields are `0`. If a pokemon has `Type 1` as `Water` and `Type 2` as `NaN`, then its `Water` field is `1` whereas all other fields are `0`.\n", - "\n", - "#### In the next cell, use One Hot Encoding to encode `Type 1` and `Type 2`. Use the pokemon type values as the names of the numerical fields you create.\n", - "\n", - "The new numerical variables you create should look like below:\n", - "\n", - "![One Hot Encoding](../images/one-hot-encoding.png)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# your code here" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Problem Solving Iteration 3\n", - "\n", - "Now we have encoded the pokemon types, we will identify the relationship between `Total` and the encoded fields. Our expectation is:\n", - "\n", - "#### There are relationships between `Total` and the encoded pokemon type variables and we need to identify the correlations.\n", - "\n", - "The information we need to collect is:\n", - "\n", - "#### How to identify the relationship between `Total` and the encoded pokemon type fields?\n", - "\n", - "There are multiple ways to answer this question. The easiest way is to use correlation. In the cell below, calculate the correlation of `Total` to each of the encoded fields. Rank the correlations and identify the #1 pokemon type that is most likely to have the highest `Total`." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# your code here" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Bonus Question\n", - "\n", - "Say now you can choose both `Type 1` and `Type 2` of the pokemon. In order to receive the best pokemon, which types will you choose?" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# your code here" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.6.9" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Challenge 2\n", + "\n", + "In this challenge we will continue working with the `Pokemon` dataset. We will attempt solving a slightly more complex problem in which we will practice the iterative data analysis process you leaned in [this video](https://www.youtube.com/watch?v=xOomNicqbkk).\n", + "\n", + "The problem statement is as follows:\n", + "\n", + "**You are at a Pokemon black market planning to buy a Pokemon for battle. All Pokemon are sold at the same price and you can only afford to buy one. You cannot choose which specific Pokemon to buy. However, you can specify the type of the Pokemon - one type that exists in either `Type 1` or `Type 2`. Which type should you choose in order to maximize your chance of receiving a good Pokemon?**\n", + "\n", + "To remind you about the 3 steps of iterative data analysis, they are:\n", + "\n", + "1. Setting Expectations\n", + "1. Collecting Information\n", + "1. Reacting to Data / Revising Expectations\n", + "\n", + "Following the iterative process, we'll guide you in completing the challenge." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "## Problem Solving Iteration 1\n", + "\n", + "In this iteration we'll analyze the problem and identify the breakthrough. The original question statement is kind of vague because we don't know what a *good pokemon* really means as represented in the data. We'll start by understanding the dataset and see if we can find some insights." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import pandas as pd" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
#NameType 1Type 2TotalHPAttackDefenseSp. AtkSp. DefSpeedGenerationLegendary
129120StaryuWaterNaN3403045557055851False
322298AzurillNormalFairy1905020402040203False
452407RoseradeGrassPoison515607065125105904False
583524RoggenrolaRockNaN2805575852525155False
151140KabutoRockWater3553080905545551False
\n", + "
" + ], + "text/plain": [ + " # Name Type 1 Type 2 Total HP Attack Defense Sp. Atk \\\n", + "129 120 Staryu Water NaN 340 30 45 55 70 \n", + "322 298 Azurill Normal Fairy 190 50 20 40 20 \n", + "452 407 Roserade Grass Poison 515 60 70 65 125 \n", + "583 524 Roggenrola Rock NaN 280 55 75 85 25 \n", + "151 140 Kabuto Rock Water 355 30 80 90 55 \n", + "\n", + " Sp. Def Speed Generation Legendary \n", + "129 55 85 1 False \n", + "322 40 20 3 False \n", + "452 105 90 4 False \n", + "583 25 15 5 False \n", + "151 45 55 1 False " + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pokemon = pd.read_csv(\"Pokemon.csv\")\n", + "pokemon.sample(5)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "From the data it seems whether a pokemon is good depends on its abilities as represented in the fields of `HP`, `Attack`, `Defense`, `Sp. Atk`, `Sp. Def`, `Speed`, and `Total`. We are not sure about `Generation` and `Legendary` because they are not necessarily the decisive factors of the pokemon abilities.\n", + "\n", + "But `HP`, `Attack`, `Defense`, `Sp. Atk`, `Sp. Def`, `Speed`, and `Total` are a lot of fields! If we look at them all at once it's very complicated. This isn't Mission Impossible but it's ideal that we tackle this kind of problem after we learn Machine Learning (which you will do in Module 3). For now, is there a way to consolidate the fields we need to look into?\n", + "\n", + "Fortunately there seems to be a way. It appears the `Total` field is computed based on the other 6 fields. But we need to prove our theory. If we can approve there is a formula to compute `Total` based on the other 6 abilities, we only need to look into `Total`.\n", + "\n", + "We have the following expectation now:\n", + "\n", + "#### The `Total` field is computed based on `HP`, `Attack`, `Defense`, `Sp. Atk`, `Sp. Def`, and `Speed`.\n", + "\n", + "We need to collect the following information:\n", + "\n", + "* **What is the formula to compute `Total`?**\n", + "* **Does the formula work for all pokemon?**\n", + "\n", + "In the cell below, make a hypothesis on how `Total` is computed and test your hypothesis." + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "verification\n", + "True 800\n", + "Name: count, dtype: int64" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "list(pokemon)\n", + "pokemon[\"Sum\"] = pokemon['HP'] + pokemon['Attack'] + pokemon['Defense'] + pokemon['Sp. Atk'] + pokemon['Sp. Def'] + pokemon['Speed']\n", + "pokemon[\"verification\"] = pokemon[\"Sum\"] == pokemon[\"Total\"]\n", + "pokemon[\"verification\"].value_counts()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Problem Solving Iteration 2\n", + "\n", + "Now that we have consolidated the abilities fields, we can update the problem statement. The new problem statement is:\n", + "\n", + "### Which pokemon type is most likely to have the highest `Total` value?\n", + "\n", + "In the updated problem statement, we assume there is a certain relationship between the `Total` and the pokemon type. But we have two *type* fields (`Type 1` and `Type 2`) that have string values. In data analysis, string fields have to be transformed to numerical format in order to be analyzed. \n", + "\n", + "In addition, keep in mind that `Type 1` always has a value but `Type 2` is sometimes empty (having the `NaN` value). Also, the pokemon type we choose may be either in `Type 1` or `Type 2`.\n", + "\n", + "Now our expectation is:\n", + "\n", + "#### `Type 1` and `Type 2` string variables need to be converted to numerical variables in order to identify the relationship between `Total` and the pokemon type.\n", + "\n", + "The information we need to collect is:\n", + "\n", + "#### How to convert two string variables to numerical?\n", + "\n", + "Let's address the first question first. You can use a method called **One Hot Encoding** which is frequently used in machine learning to encode categorical string variables to numerical. The idea is to gather all the possible string values in a categorical field and create a numerical field for each unique string value. Each of those numerical fields uses `1` and `0` to indicate whether the data record has the corresponding categorical value. A detailed explanation of One Hot Encoding can be found in [this article](https://hackernoon.com/what-is-one-hot-encoding-why-and-when-do-you-have-to-use-it-e3c6186d008f). You will formally learn it in Module 3.\n", + "\n", + "For instance, if a pokemon has `Type 1` as `Poison` and `Type 2` as `Fire`, then its `Poison` and `Fire` fields are `1` whereas all other fields are `0`. If a pokemon has `Type 1` as `Water` and `Type 2` as `NaN`, then its `Water` field is `1` whereas all other fields are `0`.\n", + "\n", + "#### In the next cell, use One Hot Encoding to encode `Type 1` and `Type 2`. Use the pokemon type values as the names of the numerical fields you create.\n", + "\n", + "The new numerical variables you create should look like below:\n", + "\n", + "![One Hot Encoding](../images/one-hot-encoding.png)" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['Fighting',\n", + " 'Water',\n", + " 'Rock',\n", + " 'Dark',\n", + " 'Dragon',\n", + " 'Electric',\n", + " 'Steel',\n", + " 'Ghost',\n", + " 'Ice',\n", + " 'Normal',\n", + " 'Flying',\n", + " 'Fairy',\n", + " 'Poison',\n", + " 'Psychic',\n", + " 'Ground',\n", + " 'Bug',\n", + " 'Fire',\n", + " 'Grass']" + ] + }, + "execution_count": 41, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "all_values = list(set(list(pokemon[\"Type 1\"])+list(pokemon[\"Type 2\"])))\n", + "all_values.pop(4)\n", + "all_values" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
FightingWaterRockDarkDragonElectricSteelGhostIceNormalFlyingFairyPoisonPsychicGroundBugFireGrass
0000000000000100001
1000000000000100001
2000000000000100001
3000000000000100001
4000000000000000010
.........................................................
795001000000001000000
796001000000001000000
797000000010000010000
798000100000000010000
799010000000000000010
\n", + "

800 rows × 18 columns

\n", + "
" + ], + "text/plain": [ + " Fighting Water Rock Dark Dragon Electric Steel Ghost Ice Normal \\\n", + "0 0 0 0 0 0 0 0 0 0 0 \n", + "1 0 0 0 0 0 0 0 0 0 0 \n", + "2 0 0 0 0 0 0 0 0 0 0 \n", + "3 0 0 0 0 0 0 0 0 0 0 \n", + "4 0 0 0 0 0 0 0 0 0 0 \n", + ".. ... ... ... ... ... ... ... ... ... ... \n", + "795 0 0 1 0 0 0 0 0 0 0 \n", + "796 0 0 1 0 0 0 0 0 0 0 \n", + "797 0 0 0 0 0 0 0 1 0 0 \n", + "798 0 0 0 1 0 0 0 0 0 0 \n", + "799 0 1 0 0 0 0 0 0 0 0 \n", + "\n", + " Flying Fairy Poison Psychic Ground Bug Fire Grass \n", + "0 0 0 1 0 0 0 0 1 \n", + "1 0 0 1 0 0 0 0 1 \n", + "2 0 0 1 0 0 0 0 1 \n", + "3 0 0 1 0 0 0 0 1 \n", + "4 0 0 0 0 0 0 1 0 \n", + ".. ... ... ... ... ... ... ... ... \n", + "795 0 1 0 0 0 0 0 0 \n", + "796 0 1 0 0 0 0 0 0 \n", + "797 0 0 0 1 0 0 0 0 \n", + "798 0 0 0 1 0 0 0 0 \n", + "799 0 0 0 0 0 0 1 0 \n", + "\n", + "[800 rows x 18 columns]" + ] + }, + "execution_count": 39, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "types = pokemon[[\"Type 1\", \"Type 2\"]]\n", + "types = types.apply(pd.Series.value_counts, axis=1)[all_values].fillna(0).astype(int)\n", + "types" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Problem Solving Iteration 3\n", + "\n", + "Now we have encoded the pokemon types, we will identify the relationship between `Total` and the encoded fields. Our expectation is:\n", + "\n", + "#### There are relationships between `Total` and the encoded pokemon type variables and we need to identify the correlations.\n", + "\n", + "The information we need to collect is:\n", + "\n", + "#### How to identify the relationship between `Total` and the encoded pokemon type fields?\n", + "\n", + "There are multiple ways to answer this question. The easiest way is to use correlation. In the cell below, calculate the correlation of `Total` to each of the encoded fields. Rank the correlations and identify the #1 pokemon type that is most likely to have the highest `Total`." + ] + }, + { + "cell_type": "code", + "execution_count": 59, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'Dragon'" + ] + }, + "execution_count": 59, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "poke = pokemon.join(types)\n", + "poke = poke.drop(columns=['Name', 'Type 1', 'Type 2', \"Sum\", \"verification\", 'HP', 'Attack', 'Defense', 'Sp. Atk', 'Sp. Def', 'Speed', 'Generation', 'Legendary',])\n", + "poke_corr = poke.corr()\n", + "poke_corr.drop(index=\"Total\", inplace=True)\n", + "poke_corr[\"Total\"].idxmax()\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Bonus Question\n", + "\n", + "Say now you can choose both `Type 1` and `Type 2` of the pokemon. In order to receive the best pokemon, which types will you choose?" + ] + }, + { + "cell_type": "code", + "execution_count": 69, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
#NameType 1Type 2TotalHPAttackDefenseSp. AtkSp. DefSpeedGenerationLegendarySumverification
76CharizardMega Charizard XFireDragon63478130111130851001False634True
159147DratiniDragonNaN3004164455050501False300True
160148DragonairDragonNaN4206184657070701False420True
161149DragoniteDragonFlying6009113495100100801False600True
196181AmpharosMega AmpharosElectricDragon6109095105165110452False610True
249230KingdraWaterDragon5407595959595852False540True
275254SceptileMega SceptileGrassDragon6307011075145851453False630True
360329VibravaGroundDragon3405070505050703False340True
361330FlygonGroundDragon520801008080801003False520True
365334AltariaDragonFlying49075709070105803False490True
366334AltariaMega AltariaDragonFairy59075110110110105803False590True
406371BagonDragonNaN3004575604030503False300True
407372ShelgonDragonNaN42065951006050503False420True
408373SalamenceDragonFlying6009513580110801003False600True
409373SalamenceMega SalamenceDragonFlying70095145130120901203False700True
417380LatiasDragonPsychic6008080901101301103True600True
418380LatiasMega LatiasDragonPsychic700801001201401501103True700True
419381LatiosDragonPsychic6008090801301101103True600True
420381LatiosMega LatiosDragonPsychic700801301001601201103True700True
425384RayquazaDragonFlying6801051509015090953True680True
426384RayquazaMega RayquazaDragonFlying7801051801001801001153True780True
491443GibleDragonGround3005870454045424False300True
492444GabiteDragonGround4106890655055824False410True
493445GarchompDragonGround6001081309580851024False600True
494445GarchompMega GarchompDragonGround70010817011512095924False700True
540483DialgaSteelDragon680100120120150100904True680True
541484PalkiaWaterDragon680901201001501201004True680True
544487GiratinaAltered FormeGhostDragon680150100120100120904True680True
545487GiratinaOrigin FormeGhostDragon680150120100120100904True680True
671610AxewDragonNaN3204687603040575False320True
672611FraxureDragonNaN41066117704050675False410True
673612HaxorusDragonNaN54076147906070975False540True
682621DruddigonDragonNaN48577120906090485False485True
694633DeinoDarkDragon3005265504550385False300True
695634ZweilousDarkDragon4207285706570585False420True
696635HydreigonDarkDragon600921059012590985False600True
706643ReshiramDragonFire680100120100150120905True680True
707644ZekromDragonElectric680100150120120100905True680True
710646KyuremDragonIce6601251309013090955True660True
711646KyuremBlack KyuremDragonIce70012517010012090955True700True
712646KyuremWhite KyuremDragonIce70012512090170100955True700True
761691DragalgePoisonDragon49465759097123446False494True
766696TyruntRockDragon3625889774545486False362True
767697TyrantrumRockDragon521821211196959716False521True
774704GoomyDragonNaN3004550355575406False300True
775705SliggooDragonNaN45268755383113606False452True
776706GoodraDragonNaN6009010070110150806False600True
790714NoibatFlyingDragon2454030354540556False245True
791715NoivernFlyingDragon53585708097801236False535True
794718Zygarde50% FormeDragonGround6001081001218195956True600True
\n", + "
" + ], + "text/plain": [ + " # Name Type 1 Type 2 Total HP Attack \\\n", + "7 6 CharizardMega Charizard X Fire Dragon 634 78 130 \n", + "159 147 Dratini Dragon NaN 300 41 64 \n", + "160 148 Dragonair Dragon NaN 420 61 84 \n", + "161 149 Dragonite Dragon Flying 600 91 134 \n", + "196 181 AmpharosMega Ampharos Electric Dragon 610 90 95 \n", + "249 230 Kingdra Water Dragon 540 75 95 \n", + "275 254 SceptileMega Sceptile Grass Dragon 630 70 110 \n", + "360 329 Vibrava Ground Dragon 340 50 70 \n", + "361 330 Flygon Ground Dragon 520 80 100 \n", + "365 334 Altaria Dragon Flying 490 75 70 \n", + "366 334 AltariaMega Altaria Dragon Fairy 590 75 110 \n", + "406 371 Bagon Dragon NaN 300 45 75 \n", + "407 372 Shelgon Dragon NaN 420 65 95 \n", + "408 373 Salamence Dragon Flying 600 95 135 \n", + "409 373 SalamenceMega Salamence Dragon Flying 700 95 145 \n", + "417 380 Latias Dragon Psychic 600 80 80 \n", + "418 380 LatiasMega Latias Dragon Psychic 700 80 100 \n", + "419 381 Latios Dragon Psychic 600 80 90 \n", + "420 381 LatiosMega Latios Dragon Psychic 700 80 130 \n", + "425 384 Rayquaza Dragon Flying 680 105 150 \n", + "426 384 RayquazaMega Rayquaza Dragon Flying 780 105 180 \n", + "491 443 Gible Dragon Ground 300 58 70 \n", + "492 444 Gabite Dragon Ground 410 68 90 \n", + "493 445 Garchomp Dragon Ground 600 108 130 \n", + "494 445 GarchompMega Garchomp Dragon Ground 700 108 170 \n", + "540 483 Dialga Steel Dragon 680 100 120 \n", + "541 484 Palkia Water Dragon 680 90 120 \n", + "544 487 GiratinaAltered Forme Ghost Dragon 680 150 100 \n", + "545 487 GiratinaOrigin Forme Ghost Dragon 680 150 120 \n", + "671 610 Axew Dragon NaN 320 46 87 \n", + "672 611 Fraxure Dragon NaN 410 66 117 \n", + "673 612 Haxorus Dragon NaN 540 76 147 \n", + "682 621 Druddigon Dragon NaN 485 77 120 \n", + "694 633 Deino Dark Dragon 300 52 65 \n", + "695 634 Zweilous Dark Dragon 420 72 85 \n", + "696 635 Hydreigon Dark Dragon 600 92 105 \n", + "706 643 Reshiram Dragon Fire 680 100 120 \n", + "707 644 Zekrom Dragon Electric 680 100 150 \n", + "710 646 Kyurem Dragon Ice 660 125 130 \n", + "711 646 KyuremBlack Kyurem Dragon Ice 700 125 170 \n", + "712 646 KyuremWhite Kyurem Dragon Ice 700 125 120 \n", + "761 691 Dragalge Poison Dragon 494 65 75 \n", + "766 696 Tyrunt Rock Dragon 362 58 89 \n", + "767 697 Tyrantrum Rock Dragon 521 82 121 \n", + "774 704 Goomy Dragon NaN 300 45 50 \n", + "775 705 Sliggoo Dragon NaN 452 68 75 \n", + "776 706 Goodra Dragon NaN 600 90 100 \n", + "790 714 Noibat Flying Dragon 245 40 30 \n", + "791 715 Noivern Flying Dragon 535 85 70 \n", + "794 718 Zygarde50% Forme Dragon Ground 600 108 100 \n", + "\n", + " Defense Sp. Atk Sp. Def Speed Generation Legendary Sum \\\n", + "7 111 130 85 100 1 False 634 \n", + "159 45 50 50 50 1 False 300 \n", + "160 65 70 70 70 1 False 420 \n", + "161 95 100 100 80 1 False 600 \n", + "196 105 165 110 45 2 False 610 \n", + "249 95 95 95 85 2 False 540 \n", + "275 75 145 85 145 3 False 630 \n", + "360 50 50 50 70 3 False 340 \n", + "361 80 80 80 100 3 False 520 \n", + "365 90 70 105 80 3 False 490 \n", + "366 110 110 105 80 3 False 590 \n", + "406 60 40 30 50 3 False 300 \n", + "407 100 60 50 50 3 False 420 \n", + "408 80 110 80 100 3 False 600 \n", + "409 130 120 90 120 3 False 700 \n", + "417 90 110 130 110 3 True 600 \n", + "418 120 140 150 110 3 True 700 \n", + "419 80 130 110 110 3 True 600 \n", + "420 100 160 120 110 3 True 700 \n", + "425 90 150 90 95 3 True 680 \n", + "426 100 180 100 115 3 True 780 \n", + "491 45 40 45 42 4 False 300 \n", + "492 65 50 55 82 4 False 410 \n", + "493 95 80 85 102 4 False 600 \n", + "494 115 120 95 92 4 False 700 \n", + "540 120 150 100 90 4 True 680 \n", + "541 100 150 120 100 4 True 680 \n", + "544 120 100 120 90 4 True 680 \n", + "545 100 120 100 90 4 True 680 \n", + "671 60 30 40 57 5 False 320 \n", + "672 70 40 50 67 5 False 410 \n", + "673 90 60 70 97 5 False 540 \n", + "682 90 60 90 48 5 False 485 \n", + "694 50 45 50 38 5 False 300 \n", + "695 70 65 70 58 5 False 420 \n", + "696 90 125 90 98 5 False 600 \n", + "706 100 150 120 90 5 True 680 \n", + "707 120 120 100 90 5 True 680 \n", + "710 90 130 90 95 5 True 660 \n", + "711 100 120 90 95 5 True 700 \n", + "712 90 170 100 95 5 True 700 \n", + "761 90 97 123 44 6 False 494 \n", + "766 77 45 45 48 6 False 362 \n", + "767 119 69 59 71 6 False 521 \n", + "774 35 55 75 40 6 False 300 \n", + "775 53 83 113 60 6 False 452 \n", + "776 70 110 150 80 6 False 600 \n", + "790 35 45 40 55 6 False 245 \n", + "791 80 97 80 123 6 False 535 \n", + "794 121 81 95 95 6 True 600 \n", + "\n", + " verification \n", + "7 True \n", + "159 True \n", + "160 True \n", + "161 True \n", + "196 True \n", + "249 True \n", + "275 True \n", + "360 True \n", + "361 True \n", + "365 True \n", + "366 True \n", + "406 True \n", + "407 True \n", + "408 True \n", + "409 True \n", + "417 True \n", + "418 True \n", + "419 True \n", + "420 True \n", + "425 True \n", + "426 True \n", + "491 True \n", + "492 True \n", + "493 True \n", + "494 True \n", + "540 True \n", + "541 True \n", + "544 True \n", + "545 True \n", + "671 True \n", + "672 True \n", + "673 True \n", + "682 True \n", + "694 True \n", + "695 True \n", + "696 True \n", + "706 True \n", + "707 True \n", + "710 True \n", + "711 True \n", + "712 True \n", + "761 True \n", + "766 True \n", + "767 True \n", + "774 True \n", + "775 True \n", + "776 True \n", + "790 True \n", + "791 True \n", + "794 True " + ] + }, + "execution_count": 69, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dragons = pokemon[(pokemon[\"Type 1\"] == \"Dragon\") | (pokemon[\"Type 2\"] == \"Dragon\")]\n", + "dragons" + ] + }, + { + "cell_type": "code", + "execution_count": 68, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['Flying',\n", + " 'Electric',\n", + " 'Steel',\n", + " 'Water',\n", + " 'Rock',\n", + " 'Ghost',\n", + " 'Ice',\n", + " 'Fairy',\n", + " 'Dark',\n", + " 'Poison',\n", + " 'Psychic',\n", + " 'Ground',\n", + " 'Fire',\n", + " 'Grass']" + ] + }, + "execution_count": 68, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dragon_values = list(set(list(dragons[\"Type 1\"])+list(dragons[\"Type 2\"])))\n", + "dragon_values.pop(0)\n", + "dragon_values.pop(6)\n", + "dragon_values" + ] + }, + { + "cell_type": "code", + "execution_count": 71, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
FlyingElectricSteelWaterRockGhostIceFairyDarkPoisonPsychicGroundFireGrass
700000000000010
15900000000000000
16000000000000000
16110000000000000
19601000000000000
24900010000000000
27500000000000001
36000000000000100
36100000000000100
36510000000000000
36600000001000000
40600000000000000
40700000000000000
40810000000000000
40910000000000000
41700000000001000
41800000000001000
41900000000001000
42000000000001000
42510000000000000
42610000000000000
49100000000000100
49200000000000100
49300000000000100
49400000000000100
54000100000000000
54100010000000000
54400000100000000
54500000100000000
67100000000000000
67200000000000000
67300000000000000
68200000000000000
69400000000100000
69500000000100000
69600000000100000
70600000000000010
70701000000000000
71000000010000000
71100000010000000
71200000010000000
76100000000010000
76600001000000000
76700001000000000
77400000000000000
77500000000000000
77600000000000000
79010000000000000
79110000000000000
79400000000000100
\n", + "
" + ], + "text/plain": [ + " Flying Electric Steel Water Rock Ghost Ice Fairy Dark Poison \\\n", + "7 0 0 0 0 0 0 0 0 0 0 \n", + "159 0 0 0 0 0 0 0 0 0 0 \n", + "160 0 0 0 0 0 0 0 0 0 0 \n", + "161 1 0 0 0 0 0 0 0 0 0 \n", + "196 0 1 0 0 0 0 0 0 0 0 \n", + "249 0 0 0 1 0 0 0 0 0 0 \n", + "275 0 0 0 0 0 0 0 0 0 0 \n", + "360 0 0 0 0 0 0 0 0 0 0 \n", + "361 0 0 0 0 0 0 0 0 0 0 \n", + "365 1 0 0 0 0 0 0 0 0 0 \n", + "366 0 0 0 0 0 0 0 1 0 0 \n", + "406 0 0 0 0 0 0 0 0 0 0 \n", + "407 0 0 0 0 0 0 0 0 0 0 \n", + "408 1 0 0 0 0 0 0 0 0 0 \n", + "409 1 0 0 0 0 0 0 0 0 0 \n", + "417 0 0 0 0 0 0 0 0 0 0 \n", + "418 0 0 0 0 0 0 0 0 0 0 \n", + "419 0 0 0 0 0 0 0 0 0 0 \n", + "420 0 0 0 0 0 0 0 0 0 0 \n", + "425 1 0 0 0 0 0 0 0 0 0 \n", + "426 1 0 0 0 0 0 0 0 0 0 \n", + "491 0 0 0 0 0 0 0 0 0 0 \n", + "492 0 0 0 0 0 0 0 0 0 0 \n", + "493 0 0 0 0 0 0 0 0 0 0 \n", + "494 0 0 0 0 0 0 0 0 0 0 \n", + "540 0 0 1 0 0 0 0 0 0 0 \n", + "541 0 0 0 1 0 0 0 0 0 0 \n", + "544 0 0 0 0 0 1 0 0 0 0 \n", + "545 0 0 0 0 0 1 0 0 0 0 \n", + "671 0 0 0 0 0 0 0 0 0 0 \n", + "672 0 0 0 0 0 0 0 0 0 0 \n", + "673 0 0 0 0 0 0 0 0 0 0 \n", + "682 0 0 0 0 0 0 0 0 0 0 \n", + "694 0 0 0 0 0 0 0 0 1 0 \n", + "695 0 0 0 0 0 0 0 0 1 0 \n", + "696 0 0 0 0 0 0 0 0 1 0 \n", + "706 0 0 0 0 0 0 0 0 0 0 \n", + "707 0 1 0 0 0 0 0 0 0 0 \n", + "710 0 0 0 0 0 0 1 0 0 0 \n", + "711 0 0 0 0 0 0 1 0 0 0 \n", + "712 0 0 0 0 0 0 1 0 0 0 \n", + "761 0 0 0 0 0 0 0 0 0 1 \n", + "766 0 0 0 0 1 0 0 0 0 0 \n", + "767 0 0 0 0 1 0 0 0 0 0 \n", + "774 0 0 0 0 0 0 0 0 0 0 \n", + "775 0 0 0 0 0 0 0 0 0 0 \n", + "776 0 0 0 0 0 0 0 0 0 0 \n", + "790 1 0 0 0 0 0 0 0 0 0 \n", + "791 1 0 0 0 0 0 0 0 0 0 \n", + "794 0 0 0 0 0 0 0 0 0 0 \n", + "\n", + " Psychic Ground Fire Grass \n", + "7 0 0 1 0 \n", + "159 0 0 0 0 \n", + "160 0 0 0 0 \n", + "161 0 0 0 0 \n", + "196 0 0 0 0 \n", + "249 0 0 0 0 \n", + "275 0 0 0 1 \n", + "360 0 1 0 0 \n", + "361 0 1 0 0 \n", + "365 0 0 0 0 \n", + "366 0 0 0 0 \n", + "406 0 0 0 0 \n", + "407 0 0 0 0 \n", + "408 0 0 0 0 \n", + "409 0 0 0 0 \n", + "417 1 0 0 0 \n", + "418 1 0 0 0 \n", + "419 1 0 0 0 \n", + "420 1 0 0 0 \n", + "425 0 0 0 0 \n", + "426 0 0 0 0 \n", + "491 0 1 0 0 \n", + "492 0 1 0 0 \n", + "493 0 1 0 0 \n", + "494 0 1 0 0 \n", + "540 0 0 0 0 \n", + "541 0 0 0 0 \n", + "544 0 0 0 0 \n", + "545 0 0 0 0 \n", + "671 0 0 0 0 \n", + "672 0 0 0 0 \n", + "673 0 0 0 0 \n", + "682 0 0 0 0 \n", + "694 0 0 0 0 \n", + "695 0 0 0 0 \n", + "696 0 0 0 0 \n", + "706 0 0 1 0 \n", + "707 0 0 0 0 \n", + "710 0 0 0 0 \n", + "711 0 0 0 0 \n", + "712 0 0 0 0 \n", + "761 0 0 0 0 \n", + "766 0 0 0 0 \n", + "767 0 0 0 0 \n", + "774 0 0 0 0 \n", + "775 0 0 0 0 \n", + "776 0 0 0 0 \n", + "790 0 0 0 0 \n", + "791 0 0 0 0 \n", + "794 0 1 0 0 " + ] + }, + "execution_count": 71, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dragon_types = dragons[[\"Type 1\", \"Type 2\"]]\n", + "dragon_types = dragon_types.apply(pd.Series.value_counts, axis=1)[dragon_values].fillna(0).astype(int)\n", + "dragon_types" + ] + }, + { + "cell_type": "code", + "execution_count": 72, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'Ice'" + ] + }, + "execution_count": 72, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "poke_dragons = dragons.join(dragon_types)\n", + "poke_dragons = poke_dragons.drop(columns=['Name', 'Type 1', 'Type 2', \"Sum\", \"verification\", 'HP', 'Attack', 'Defense', 'Sp. Atk', 'Sp. Def', 'Speed', 'Generation', 'Legendary',])\n", + "dragon_corr = poke_dragons.corr()\n", + "dragon_corr.drop(index=\"Total\", inplace=True)\n", + "dragon_corr[\"Total\"].idxmax()" + ] + }, + { + "cell_type": "code", + "execution_count": 74, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
#NameType 1Type 2TotalHPAttackDefenseSp. AtkSp. DefSpeedGenerationLegendarySumverification
710646KyuremDragonIce6601251309013090955True660True
711646KyuremBlack KyuremDragonIce70012517010012090955True700True
712646KyuremWhite KyuremDragonIce70012512090170100955True700True
\n", + "
" + ], + "text/plain": [ + " # Name Type 1 Type 2 Total HP Attack Defense \\\n", + "710 646 Kyurem Dragon Ice 660 125 130 90 \n", + "711 646 KyuremBlack Kyurem Dragon Ice 700 125 170 100 \n", + "712 646 KyuremWhite Kyurem Dragon Ice 700 125 120 90 \n", + "\n", + " Sp. Atk Sp. Def Speed Generation Legendary Sum verification \n", + "710 130 90 95 5 True 660 True \n", + "711 120 90 95 5 True 700 True \n", + "712 170 100 95 5 True 700 True " + ] + }, + "execution_count": 74, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "ice_dragons = pokemon[((pokemon[\"Type 1\"] == \"Dragon\") & (pokemon[\"Type 2\"] == \"Ice\")) | (pokemon[\"Type 1\"] == \"Ice\") & (pokemon[\"Type 2\"] == \"Dragon\")]\n", + "ice_dragons" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "base", + "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.12.4" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/your-code/challenge-3.ipynb b/your-code/challenge-3.ipynb index a42a586..7ce8a5d 100644 --- a/your-code/challenge-3.ipynb +++ b/your-code/challenge-3.ipynb @@ -1,147 +1,487 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Challenge 3\n", - "\n", - "In this challenge we will work on the `Orders` data set. In your work you will apply the thinking process and workflow we showed you in Challenge 2.\n", - "\n", - "You are serving as a Business Intelligence Analyst at the headquarter of an international fashion goods chain store. Your boss today asked you to do two things for her:\n", - "\n", - "**First, identify two groups of customers from the data set.** The first group is **VIP Customers** whose **aggregated expenses** at your global chain stores are **above the 95th percentile** (aka. 0.95 quantile). The second group is **Preferred Customers** whose **aggregated expenses** are **between the 75th and 95th percentile**.\n", - "\n", - "**Second, identify which country has the most of your VIP customers, and which country has the most of your VIP+Preferred Customers combined.**" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Q1: How to identify VIP & Preferred Customers?\n", - "\n", - "We start by importing all the required libraries:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# import required libraries\n", - "import numpy as np\n", - "import pandas as pd" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Next, extract and import `Orders` dataset into a dataframe variable called `orders`. Print the head of `orders` to overview the data:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# your code here" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---\n", - "\n", - "\"Identify VIP and Preferred Customers\" is the non-technical goal of your boss. You need to translate that goal into technical languages that data analysts use:\n", - "\n", - "## How to label customers whose aggregated `amount_spent` is in a given quantile range?\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We break down the main problem into several sub problems:\n", - "\n", - "#### Sub Problem 1: How to aggregate the `amount_spent` for unique customers?\n", - "\n", - "#### Sub Problem 2: How to select customers whose aggregated `amount_spent` is in a given quantile range?\n", - "\n", - "#### Sub Problem 3: How to label selected customers as \"VIP\" or \"Preferred\"?\n", - "\n", - "*Note: If you want to break down the main problem in a different way, please feel free to revise the sub problems above.*\n", - "\n", - "Now in the workspace below, tackle each of the sub problems using the iterative problem solving workflow. Insert cells as necessary to write your codes and explain your steps." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# your code here" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now we'll leave it to you to solve Q2 & Q3, which you can leverage from your solution for Q1:\n", - "\n", - "## Q2: How to identify which country has the most VIP Customers?" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# your code here" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Q3: How to identify which country has the most VIP+Preferred Customers combined?" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# your code here" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.6.9" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Challenge 3\n", + "\n", + "In this challenge we will work on the `Orders` data set. In your work you will apply the thinking process and workflow we showed you in Challenge 2.\n", + "\n", + "You are serving as a Business Intelligence Analyst at the headquarter of an international fashion goods chain store. Your boss today asked you to do two things for her:\n", + "\n", + "**First, identify two groups of customers from the data set.** The first group is **VIP Customers** whose **aggregated expenses** at your global chain stores are **above the 95th percentile** (aka. 0.95 quantile). The second group is **Preferred Customers** whose **aggregated expenses** are **between the 75th and 95th percentile**.\n", + "\n", + "**Second, identify which country has the most of your VIP customers, and which country has the most of your VIP+Preferred Customers combined.**" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Q1: How to identify VIP & Preferred Customers?\n", + "\n", + "We start by importing all the required libraries:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "# import required libraries\n", + "import numpy as np\n", + "import pandas as pd" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Next, extract and import `Orders` dataset into a dataframe variable called `orders`. Print the head of `orders` to overview the data:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Unnamed: 0InvoiceNoStockCodeyearmonthdayhourDescriptionQuantityInvoiceDateUnitPriceCustomerIDCountryamount_spent
0053636585123A20101238white hanging heart t-light holder62010-12-01 08:26:002.5517850United Kingdom15.30
115363657105320101238white metal lantern62010-12-01 08:26:003.3917850United Kingdom20.34
2253636584406B20101238cream cupid hearts coat hanger82010-12-01 08:26:002.7517850United Kingdom22.00
3353636584029G20101238knitted union flag hot water bottle62010-12-01 08:26:003.3917850United Kingdom20.34
4453636584029E20101238red woolly hottie white heart.62010-12-01 08:26:003.3917850United Kingdom20.34
\n", + "
" + ], + "text/plain": [ + " Unnamed: 0 InvoiceNo StockCode year month day hour \\\n", + "0 0 536365 85123A 2010 12 3 8 \n", + "1 1 536365 71053 2010 12 3 8 \n", + "2 2 536365 84406B 2010 12 3 8 \n", + "3 3 536365 84029G 2010 12 3 8 \n", + "4 4 536365 84029E 2010 12 3 8 \n", + "\n", + " Description Quantity InvoiceDate \\\n", + "0 white hanging heart t-light holder 6 2010-12-01 08:26:00 \n", + "1 white metal lantern 6 2010-12-01 08:26:00 \n", + "2 cream cupid hearts coat hanger 8 2010-12-01 08:26:00 \n", + "3 knitted union flag hot water bottle 6 2010-12-01 08:26:00 \n", + "4 red woolly hottie white heart. 6 2010-12-01 08:26:00 \n", + "\n", + " UnitPrice CustomerID Country amount_spent \n", + "0 2.55 17850 United Kingdom 15.30 \n", + "1 3.39 17850 United Kingdom 20.34 \n", + "2 2.75 17850 United Kingdom 22.00 \n", + "3 3.39 17850 United Kingdom 20.34 \n", + "4 3.39 17850 United Kingdom 20.34 " + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df = pd.read_csv(\"Orders.zip\")\n", + "df.head()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---\n", + "\n", + "\"Identify VIP and Preferred Customers\" is the non-technical goal of your boss. You need to translate that goal into technical languages that data analysts use:\n", + "\n", + "## How to label customers whose aggregated `amount_spent` is in a given quantile range?\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We break down the main problem into several sub problems:\n", + "\n", + "#### Sub Problem 1: How to aggregate the `amount_spent` for unique customers?\n", + "\n", + "#### Sub Problem 2: How to select customers whose aggregated `amount_spent` is in a given quantile range?\n", + "\n", + "#### Sub Problem 3: How to label selected customers as \"VIP\" or \"Preferred\"?\n", + "\n", + "*Note: If you want to break down the main problem in a different way, please feel free to revise the sub problems above.*\n", + "\n", + "Now in the workspace below, tackle each of the sub problems using the iterative problem solving workflow. Insert cells as necessary to write your codes and explain your steps." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "4339" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df[\"CustomerID\"].nunique()" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [], + "source": [ + "spent_by_client = df.groupby([\"CustomerID\"])[\"amount_spent\"].agg(\"sum\").sort_values(ascending=False).reset_index()\n", + "q95 = spent_by_client[\"amount_spent\"].quantile(.95)\n", + "q75 = spent_by_client[\"amount_spent\"].quantile(.75)" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [], + "source": [ + "def categorize (number):\n", + " if number >= q95: return \"VIP\"\n", + " elif number >= q75: return \"Preferred\"\n", + " else: return\n" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
CustomerIDamount_spentcategory
1216163481469.45None
383131833957.78Preferred
268117880458.92None
289616776388.28None
647138512651.46Preferred
1021618010254.18VIP
1241161031429.64None
1243140351428.02None
461515918641.01VIP
161576956252.72VIP
\n", + "
" + ], + "text/plain": [ + " CustomerID amount_spent category\n", + "1216 16348 1469.45 None\n", + "383 13183 3957.78 Preferred\n", + "2681 17880 458.92 None\n", + "2896 16776 388.28 None\n", + "647 13851 2651.46 Preferred\n", + "102 16180 10254.18 VIP\n", + "1241 16103 1429.64 None\n", + "1243 14035 1428.02 None\n", + "46 15159 18641.01 VIP\n", + "16 15769 56252.72 VIP" + ] + }, + "execution_count": 35, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "spent_by_client[\"category\"] = spent_by_client[\"amount_spent\"].apply(categorize)\n", + "spent_by_client.sample(10)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we'll leave it to you to solve Q2 & Q3, which you can leverage from your solution for Q1:\n", + "\n", + "## Q2: How to identify which country has the most VIP Customers?" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Country United Kingdom\n", + "amount_spent 3417798.95\n", + "dtype: object" + ] + }, + "execution_count": 46, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "spent_by_client_country = spent_by_client.merge(df[[\"CustomerID\", \"Country\"]], on=\"CustomerID\", how=\"left\").drop_duplicates()\n", + "vips = spent_by_client_country[spent_by_client_country[\"category\"] == \"VIP\"]\n", + "vips.groupby([\"Country\"])[\"amount_spent\"].agg(\"sum\").reset_index().max()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Q3: How to identify which country has the most VIP+Preferred Customers combined?" + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Country United Kingdom\n", + "amount_spent 5624512.711\n", + "dtype: object" + ] + }, + "execution_count": 50, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "spent_by_client_country = spent_by_client.merge(df[[\"CustomerID\", \"Country\"]], on=\"CustomerID\", how=\"left\").drop_duplicates()\n", + "vip_and_preferred = spent_by_client_country[(spent_by_client_country[\"category\"] == \"VIP\") | (spent_by_client_country[\"category\"] == \"Preferred\")]\n", + "vip_and_preferred.groupby([\"Country\"])[\"amount_spent\"].agg(\"sum\").reset_index().max()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "base", + "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.12.4" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +}