{ "cells": [ { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Merge\n", "\n", "Often, we will want perform joint analysis on data from different sources.\n", "\n", "For example, when analyzing the regional sales for a company, we might\n", "want to include industry aggregates or demographic information for each\n", "region.\n", "\n", "Or perhaps we are working with product-level data, have a list of\n", "product groups in a separate dataset, and want to compute aggregate\n", "statistics for each group.\n", "\n", "**Outcomes**\n", "\n", "- Know the different pandas routines for combining datasets \n", "- Know when to use `pd.concat` vs `pd.merge` vs `pd.join` \n", "- Be able to apply the three main combining routines \n", "\n", "\n", "**Data**\n", "\n", "- WDI data on GDP components, population, and square miles of countries \n", "- Book ratings: 6,000,000 ratings for the 10,000 most rated books on\n", " [Goodreads](https://www.goodreads.com/) \n", "- Details for all delayed US domestic flights in November 2016,\n", " obtained from the [Bureau of Transportation\n", " Statistics](https://www.transtats.bts.gov/DL_SelectFields.asp?Table_ID=236&DB_Short_Name=On-Time) " ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "hide-output": false, "slideshow": { "slide_type": "-" } }, "outputs": [], "source": [ "import pandas as pd\n", "import qeds\n", "\n", "%matplotlib inline\n", "\n", "# activate plot theme\n", "qeds.themes.mpl_style();\n", "\n", "from IPython.display import display" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "hide-output": false, "slideshow": { "slide_type": "-" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "MultiIndex: 72 entries, ('Canada', 2017) to ('United States', 2000)\n", "Data columns (total 5 columns):\n", " # Column Non-Null Count Dtype \n", "--- ------ -------------- ----- \n", " 0 GovExpend 72 non-null float64\n", " 1 Consumption 72 non-null float64\n", " 2 Exports 72 non-null float64\n", " 3 Imports 72 non-null float64\n", " 4 GDP 72 non-null float64\n", "dtypes: float64(5)\n", "memory usage: 4.0+ KB\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", "
GovExpendConsumptionExportsImportsGDP
country
Canada0.3726651.0954750.5828310.6000311.868164
Germany0.7455792.1120091.9305631.6663483.883870
United Kingdom0.5495381.8091540.8626290.9331452.818704
United States2.40574312.0192662.2870713.06995417.348627
\n", "
" ], "text/plain": [ " GovExpend Consumption Exports Imports GDP\n", "country \n", "Canada 0.372665 1.095475 0.582831 0.600031 1.868164\n", "Germany 0.745579 2.112009 1.930563 1.666348 3.883870\n", "United Kingdom 0.549538 1.809154 0.862629 0.933145 2.818704\n", "United States 2.405743 12.019266 2.287071 3.069954 17.348627" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# from WDI. Units trillions of 2010 USD\n", "url = \"https://datascience.quantecon.org/assets/data/wdi_data.csv\"\n", "wdi = pd.read_csv(url).set_index([\"country\", \"year\"])\n", "wdi.info()\n", "\n", "wdi2017 = wdi.xs(2017, level=\"year\")\n", "wdi2017" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "hide-output": false, "slideshow": { "slide_type": "-" } }, "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", "
GovExpendConsumptionExportsImportsGDP
countryyear
Canada20170.3726651.0954750.5828310.6000311.868164
20160.3648991.0584260.5763940.5757751.814016
Germany20170.7455792.1120091.9305631.6663483.883870
20160.7340142.0756151.8449491.5894953.801859
United Kingdom20170.5495381.8091540.8626290.9331452.818704
20160.5505961.7723480.8167920.9014942.768241
United States20172.40574312.0192662.2870713.06995417.348627
20162.40798111.7221332.2199372.93600416.972348
\n", "
" ], "text/plain": [ " GovExpend Consumption Exports Imports GDP\n", "country year \n", "Canada 2017 0.372665 1.095475 0.582831 0.600031 1.868164\n", " 2016 0.364899 1.058426 0.576394 0.575775 1.814016\n", "Germany 2017 0.745579 2.112009 1.930563 1.666348 3.883870\n", " 2016 0.734014 2.075615 1.844949 1.589495 3.801859\n", "United Kingdom 2017 0.549538 1.809154 0.862629 0.933145 2.818704\n", " 2016 0.550596 1.772348 0.816792 0.901494 2.768241\n", "United States 2017 2.405743 12.019266 2.287071 3.069954 17.348627\n", " 2016 2.407981 11.722133 2.219937 2.936004 16.972348" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "wdi2016_17 = wdi.loc[pd.IndexSlice[:, [2016, 2017]],: ]\n", "wdi2016_17" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "hide-output": false, "slideshow": { "slide_type": "-" } }, "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", "
sq_miles
country
United States3.8000
Canada3.8000
Germany0.1370
United Kingdom0.0936
Russia6.6000
\n", "
" ], "text/plain": [ " sq_miles\n", "country \n", "United States 3.8000\n", "Canada 3.8000\n", "Germany 0.1370\n", "United Kingdom 0.0936\n", "Russia 6.6000" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Data from https://www.nationmaster.com/country-info/stats/Geography/Land-area/Square-miles\n", "# units -- millions of square miles\n", "sq_miles = pd.Series({\n", " \"United States\": 3.8,\n", " \"Canada\": 3.8,\n", " \"Germany\": 0.137,\n", " \"United Kingdom\": 0.0936,\n", " \"Russia\": 6.6,\n", "}, name=\"sq_miles\").to_frame()\n", "sq_miles.index.name = \"country\"\n", "sq_miles" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "hide-output": false, "slideshow": { "slide_type": "-" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "MultiIndex: 72 entries, ('Canada', 2017) to ('United States', 2000)\n", "Data columns (total 1 columns):\n", " # Column Non-Null Count Dtype \n", "--- ------ -------------- ----- \n", " 0 Population 72 non-null float64\n", "dtypes: float64(1)\n", "memory usage: 1.8+ KB\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", "
Population
countryyear
Canada201736.540268
201636.109487
201535.702908
201435.437435
201335.082954
201234.714222
201134.339328
201034.004889
200933.628895
200833.247118
\n", "
" ], "text/plain": [ " Population\n", "country year \n", "Canada 2017 36.540268\n", " 2016 36.109487\n", " 2015 35.702908\n", " 2014 35.437435\n", " 2013 35.082954\n", " 2012 34.714222\n", " 2011 34.339328\n", " 2010 34.004889\n", " 2009 33.628895\n", " 2008 33.247118" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# from WDI. Units millions of people\n", "pop_url = \"https://datascience.quantecon.org/assets/data/wdi_population.csv\"\n", "pop = pd.read_csv(pop_url).set_index([\"country\", \"year\"])\n", "pop.info()\n", "pop.head(10)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Suppose that we were asked to compute a number of statistics with the data above:\n", "\n", "- As a measure of land usage or productivity, what is Consumption per square mile? \n", "- What is GDP per capita (per person) for each country in each year? How about\n", " Consumption per person? \n", "- What is the population density of each country? How much does it change over time? \n", "\n", "\n", "Notice that to answer any of the questions from above, we will have to use data\n", "from more than one of our DataFrames.\n", "\n", "In this lecture, we will learn many techniques for combining datasets that\n", "originate from different sources, careful to ensure that data is properly\n", "aligned.\n", "\n", "In pandas three main methods can combine datasets:\n", "\n", "1. `pd.concat([dfs...])` \n", "1. `pd.merge(df1, df2)` \n", "1. `df1.join(df2)` \n", "\n", "\n", "We’ll look at each one." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## `pd.concat`\n", "\n", "The `pd.concat` function is used to stack two or more DataFrames\n", "together.\n", "\n", "An example of when you might want to do this is if you have monthly data\n", "in separate files on your computer and would like to have 1 year of data\n", "in a single DataFrame.\n", "\n", "The first argument to `pd.concat` is a list of DataFrames to be\n", "stitched together.\n", "\n", "The other commonly used argument is named `axis`.\n", "\n", "As we have seen before, many pandas functions have an `axis` argument\n", "that specifies whether a particular operation should happen down rows\n", "(`axis=0`) or along columns (`axis=1`).\n", "\n", "In the context of `pd.concat`, setting `axis=0` (the default case)\n", "will stack DataFrames on top of one another while `axis=1` stacks them\n", "side by side.\n", "\n", "We’ll look at each case separately." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### `axis=0`\n", "\n", "When we call `pd.concat` and set `axis=0`, the list of DataFrames\n", "passed in the first argument will be stacked on top of one another.\n", "\n", "Let’s try it out here." ] }, { "cell_type": "code", "execution_count": 7, "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", "
GovExpendConsumptionExportsImportsGDP
country
Canada0.3726651.0954750.5828310.6000311.868164
Germany0.7455792.1120091.9305631.6663483.883870
United Kingdom0.5495381.8091540.8626290.9331452.818704
United States2.40574312.0192662.2870713.06995417.348627
\n", "
" ], "text/plain": [ " GovExpend Consumption Exports Imports GDP\n", "country \n", "Canada 0.372665 1.095475 0.582831 0.600031 1.868164\n", "Germany 0.745579 2.112009 1.930563 1.666348 3.883870\n", "United Kingdom 0.549538 1.809154 0.862629 0.933145 2.818704\n", "United States 2.405743 12.019266 2.287071 3.069954 17.348627" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "wdi2017" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
sq_miles
country
United States3.8000
Canada3.8000
Germany0.1370
United Kingdom0.0936
Russia6.6000
\n", "
" ], "text/plain": [ " sq_miles\n", "country \n", "United States 3.8000\n", "Canada 3.8000\n", "Germany 0.1370\n", "United Kingdom 0.0936\n", "Russia 6.6000" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sq_miles" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "hide-output": false, "slideshow": { "slide_type": "-" } }, "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", "
GovExpendConsumptionExportsImportsGDPsq_miles
country
Canada0.3726651.0954750.5828310.6000311.868164NaN
Germany0.7455792.1120091.9305631.6663483.883870NaN
United Kingdom0.5495381.8091540.8626290.9331452.818704NaN
United States2.40574312.0192662.2870713.06995417.348627NaN
United StatesNaNNaNNaNNaNNaN3.8000
CanadaNaNNaNNaNNaNNaN3.8000
GermanyNaNNaNNaNNaNNaN0.1370
United KingdomNaNNaNNaNNaNNaN0.0936
RussiaNaNNaNNaNNaNNaN6.6000
\n", "
" ], "text/plain": [ " GovExpend Consumption Exports Imports GDP \\\n", "country \n", "Canada 0.372665 1.095475 0.582831 0.600031 1.868164 \n", "Germany 0.745579 2.112009 1.930563 1.666348 3.883870 \n", "United Kingdom 0.549538 1.809154 0.862629 0.933145 2.818704 \n", "United States 2.405743 12.019266 2.287071 3.069954 17.348627 \n", "United States NaN NaN NaN NaN NaN \n", "Canada NaN NaN NaN NaN NaN \n", "Germany NaN NaN NaN NaN NaN \n", "United Kingdom NaN NaN NaN NaN NaN \n", "Russia NaN NaN NaN NaN NaN \n", "\n", " sq_miles \n", "country \n", "Canada NaN \n", "Germany NaN \n", "United Kingdom NaN \n", "United States NaN \n", "United States 3.8000 \n", "Canada 3.8000 \n", "Germany 0.1370 \n", "United Kingdom 0.0936 \n", "Russia 6.6000 " ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# equivalent to pd.concat([wdi2017, sq_miles]) -- axis=0 is default\n", "pd.concat([wdi2017, sq_miles], axis=0)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "Notice a few things:\n", "\n", "- \n", "
\n", "
The number of rows in the output is the total number
\n", "
\n", " of rows in all inputs. The labels are all from the original\n", " DataFrames. \n", "
\n", " \n", "
\n", " \n", "- The column labels are all the distinct column labels from all the inputs. \n", "- For columns that appeared only in one input, the value for all row labels\n", " originating from a different input is equal to `NaN` (marked as missing). " ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### `axis=1`\n", "\n", "In this example, concatenating by stacking\n", "side-by-side makes more sense.\n", "\n", "We accomplish this by passing `axis=1` to `pd.concat`:" ] }, { "cell_type": "code", "execution_count": 11, "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", "
GovExpendConsumptionExportsImportsGDP
country
Canada0.3726651.0954750.5828310.6000311.868164
Germany0.7455792.1120091.9305631.6663483.883870
United Kingdom0.5495381.8091540.8626290.9331452.818704
United States2.40574312.0192662.2870713.06995417.348627
\n", "
" ], "text/plain": [ " GovExpend Consumption Exports Imports GDP\n", "country \n", "Canada 0.372665 1.095475 0.582831 0.600031 1.868164\n", "Germany 0.745579 2.112009 1.930563 1.666348 3.883870\n", "United Kingdom 0.549538 1.809154 0.862629 0.933145 2.818704\n", "United States 2.405743 12.019266 2.287071 3.069954 17.348627" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "wdi2017" ] }, { "cell_type": "code", "execution_count": 12, "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", "
sq_miles
country
United States3.8000
Canada3.8000
Germany0.1370
United Kingdom0.0936
Russia6.6000
\n", "
" ], "text/plain": [ " sq_miles\n", "country \n", "United States 3.8000\n", "Canada 3.8000\n", "Germany 0.1370\n", "United Kingdom 0.0936\n", "Russia 6.6000" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sq_miles" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "hide-output": false, "slideshow": { "slide_type": "-" } }, "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", "
GovExpendConsumptionExportsImportsGDPsq_miles
Canada0.3726651.0954750.5828310.6000311.8681643.8000
Germany0.7455792.1120091.9305631.6663483.8838700.1370
United Kingdom0.5495381.8091540.8626290.9331452.8187040.0936
United States2.40574312.0192662.2870713.06995417.3486273.8000
RussiaNaNNaNNaNNaNNaN6.6000
\n", "
" ], "text/plain": [ " GovExpend Consumption Exports Imports GDP \\\n", "Canada 0.372665 1.095475 0.582831 0.600031 1.868164 \n", "Germany 0.745579 2.112009 1.930563 1.666348 3.883870 \n", "United Kingdom 0.549538 1.809154 0.862629 0.933145 2.818704 \n", "United States 2.405743 12.019266 2.287071 3.069954 17.348627 \n", "Russia NaN NaN NaN NaN NaN \n", "\n", " sq_miles \n", "Canada 3.8000 \n", "Germany 0.1370 \n", "United Kingdom 0.0936 \n", "United States 3.8000 \n", "Russia 6.6000 " ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pd.concat([wdi2017, sq_miles], axis=1)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "Notice here that\n", "\n", "- The index entries are all unique index entries that appeared in any DataFrame. \n", "- The column labels are all column labels from the inputs. \n", "- As `wdi2017` didn’t have a `Russia` row, the value for all of its columns\n", " is `NaN`. \n", "\n", "\n", "Now we can answer one of our questions from above: What is\n", "Consumption per square mile?" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "hide-output": false, "slideshow": { "slide_type": "-" } }, "outputs": [ { "data": { "text/plain": [ "Canada 0.288283\n", "Germany 15.416124\n", "United Kingdom 19.328569\n", "United States 3.162965\n", "Russia NaN\n", "dtype: float64" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "temp = pd.concat([wdi2017, sq_miles], axis=1)\n", "temp[\"Consumption\"] / temp[\"sq_miles\"]" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## `pd.merge`\n", "\n", "`pd.merge` operates on two DataFrames at a time and is primarily used\n", "to bring columns from one DataFrame into another, *aligning* data based\n", "on one or more “key” columns.\n", "\n", "This is a somewhat difficult concept to grasp by reading, so let’s look at some\n", "examples." ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
GovExpendConsumptionExportsImportsGDPsq_miles
Canada0.3726651.0954750.5828310.6000311.8681643.8000
Germany0.7455792.1120091.9305631.6663483.8838700.1370
United Kingdom0.5495381.8091540.8626290.9331452.8187040.0936
United States2.40574312.0192662.2870713.06995417.3486273.8000
RussiaNaNNaNNaNNaNNaN6.6000
\n", "
" ], "text/plain": [ " GovExpend Consumption Exports Imports GDP \\\n", "Canada 0.372665 1.095475 0.582831 0.600031 1.868164 \n", "Germany 0.745579 2.112009 1.930563 1.666348 3.883870 \n", "United Kingdom 0.549538 1.809154 0.862629 0.933145 2.818704 \n", "United States 2.405743 12.019266 2.287071 3.069954 17.348627 \n", "Russia NaN NaN NaN NaN NaN \n", "\n", " sq_miles \n", "Canada 3.8000 \n", "Germany 0.1370 \n", "United Kingdom 0.0936 \n", "United States 3.8000 \n", "Russia 6.6000 " ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pd.concat([wdi2017, sq_miles], axis=1)" ] }, { "cell_type": "code", "execution_count": 97, "metadata": { "hide-output": false, "slideshow": { "slide_type": "-" } }, "outputs": [], "source": [ "foo = pd.merge(wdi2017, sq_miles, on=\"country\")" ] }, { "cell_type": "code", "execution_count": 99, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
GovExpendConsumptionExportsImportsGDP
country
Canada0.3726651.0954750.5828310.6000311.868164
Germany0.7455792.1120091.9305631.6663483.883870
United Kingdom0.5495381.8091540.8626290.9331452.818704
United States2.40574312.0192662.2870713.06995417.348627
\n", "
" ], "text/plain": [ " GovExpend Consumption Exports Imports GDP\n", "country \n", "Canada 0.372665 1.095475 0.582831 0.600031 1.868164\n", "Germany 0.745579 2.112009 1.930563 1.666348 3.883870\n", "United Kingdom 0.549538 1.809154 0.862629 0.933145 2.818704\n", "United States 2.405743 12.019266 2.287071 3.069954 17.348627" ] }, "execution_count": 99, "metadata": {}, "output_type": "execute_result" } ], "source": [ "wdi2017" ] }, { "cell_type": "code", "execution_count": 100, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
sq_miles
country
United States3.8000
Canada3.8000
Germany0.1370
United Kingdom0.0936
Russia6.6000
\n", "
" ], "text/plain": [ " sq_miles\n", "country \n", "United States 3.8000\n", "Canada 3.8000\n", "Germany 0.1370\n", "United Kingdom 0.0936\n", "Russia 6.6000" ] }, "execution_count": 100, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sq_miles" ] }, { "cell_type": "code", "execution_count": 98, "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", "
GovExpendConsumptionExportsImportsGDPsq_miles
country
Canada0.3726651.0954750.5828310.6000311.8681643.8000
Germany0.7455792.1120091.9305631.6663483.8838700.1370
United Kingdom0.5495381.8091540.8626290.9331452.8187040.0936
United States2.40574312.0192662.2870713.06995417.3486273.8000
\n", "
" ], "text/plain": [ " GovExpend Consumption Exports Imports GDP \\\n", "country \n", "Canada 0.372665 1.095475 0.582831 0.600031 1.868164 \n", "Germany 0.745579 2.112009 1.930563 1.666348 3.883870 \n", "United Kingdom 0.549538 1.809154 0.862629 0.933145 2.818704 \n", "United States 2.405743 12.019266 2.287071 3.069954 17.348627 \n", "\n", " sq_miles \n", "country \n", "Canada 3.8000 \n", "Germany 0.1370 \n", "United Kingdom 0.0936 \n", "United States 3.8000 " ] }, "execution_count": 98, "metadata": {}, "output_type": "execute_result" } ], "source": [ "foo" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "-" } }, "source": [ "The output here looks very similar to what we saw with `concat` and\n", "`axis=1`, except that the row for `Russia` does not appear.\n", "\n", "We will talk more about why this happened soon." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "For now, let’s look at a slightly more intriguing example:" ] }, { "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", "
GovExpendConsumptionExportsImportsGDP
countryyear
Canada20170.3726651.0954750.5828310.6000311.868164
20160.3648991.0584260.5763940.5757751.814016
Germany20170.7455792.1120091.9305631.6663483.883870
20160.7340142.0756151.8449491.5894953.801859
United Kingdom20170.5495381.8091540.8626290.9331452.818704
20160.5505961.7723480.8167920.9014942.768241
United States20172.40574312.0192662.2870713.06995417.348627
20162.40798111.7221332.2199372.93600416.972348
\n", "
" ], "text/plain": [ " GovExpend Consumption Exports Imports GDP\n", "country year \n", "Canada 2017 0.372665 1.095475 0.582831 0.600031 1.868164\n", " 2016 0.364899 1.058426 0.576394 0.575775 1.814016\n", "Germany 2017 0.745579 2.112009 1.930563 1.666348 3.883870\n", " 2016 0.734014 2.075615 1.844949 1.589495 3.801859\n", "United Kingdom 2017 0.549538 1.809154 0.862629 0.933145 2.818704\n", " 2016 0.550596 1.772348 0.816792 0.901494 2.768241\n", "United States 2017 2.405743 12.019266 2.287071 3.069954 17.348627\n", " 2016 2.407981 11.722133 2.219937 2.936004 16.972348" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "wdi2016_17" ] }, { "cell_type": "code", "execution_count": 18, "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", "
sq_miles
country
United States3.8000
Canada3.8000
Germany0.1370
United Kingdom0.0936
Russia6.6000
\n", "
" ], "text/plain": [ " sq_miles\n", "country \n", "United States 3.8000\n", "Canada 3.8000\n", "Germany 0.1370\n", "United Kingdom 0.0936\n", "Russia 6.6000" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sq_miles" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "hide-output": false, "slideshow": { "slide_type": "-" } }, "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", "
GovExpendConsumptionExportsImportsGDPsq_miles
country
Canada0.3726651.0954750.5828310.6000311.8681643.8000
Canada0.3648991.0584260.5763940.5757751.8140163.8000
Germany0.7455792.1120091.9305631.6663483.8838700.1370
Germany0.7340142.0756151.8449491.5894953.8018590.1370
United Kingdom0.5495381.8091540.8626290.9331452.8187040.0936
United Kingdom0.5505961.7723480.8167920.9014942.7682410.0936
United States2.40574312.0192662.2870713.06995417.3486273.8000
United States2.40798111.7221332.2199372.93600416.9723483.8000
\n", "
" ], "text/plain": [ " GovExpend Consumption Exports Imports GDP \\\n", "country \n", "Canada 0.372665 1.095475 0.582831 0.600031 1.868164 \n", "Canada 0.364899 1.058426 0.576394 0.575775 1.814016 \n", "Germany 0.745579 2.112009 1.930563 1.666348 3.883870 \n", "Germany 0.734014 2.075615 1.844949 1.589495 3.801859 \n", "United Kingdom 0.549538 1.809154 0.862629 0.933145 2.818704 \n", "United Kingdom 0.550596 1.772348 0.816792 0.901494 2.768241 \n", "United States 2.405743 12.019266 2.287071 3.069954 17.348627 \n", "United States 2.407981 11.722133 2.219937 2.936004 16.972348 \n", "\n", " sq_miles \n", "country \n", "Canada 3.8000 \n", "Canada 3.8000 \n", "Germany 0.1370 \n", "Germany 0.1370 \n", "United Kingdom 0.0936 \n", "United Kingdom 0.0936 \n", "United States 3.8000 \n", "United States 3.8000 " ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pd.merge(wdi2016_17, sq_miles, on=\"country\")" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "-" } }, "source": [ "Here’s how we think about what happened:\n", "\n", "- The data in `wdi2016_17` is copied over exactly as is. \n", "- Because `country` was on the index for both DataFrames, it is on the\n", " index of the output. \n", "- We lost the year on the index – we’ll work on getting it back below. \n", "- The additional column in `sq_miles` was added to column labels for the\n", " output. \n", "- The data from the `sq_miles` column was added to the output by looking up\n", " rows where the `country` in the two DataFrames lined up.\n", " - Note that all the countries appeared twice, and the data in `sq_miles` was repeated. This is because `wdi2016_17` had two rows for each country.\n", " - Also note that because `Russia` did not appear in `wdi2016_17`, the value `sq_miles.loc[\"Russia\"]` (i.e. `6.6`) is not used the output. " ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "How do we get the year back?\n", "\n", "We must first call `reset_index` on `wdi2016_17` so\n", "that in the first step when all columns are copied over, `year` is included." ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
sq_miles
country
United States3.8000
Canada3.8000
Germany0.1370
United Kingdom0.0936
Russia6.6000
\n", "
" ], "text/plain": [ " sq_miles\n", "country \n", "United States 3.8000\n", "Canada 3.8000\n", "Germany 0.1370\n", "United Kingdom 0.0936\n", "Russia 6.6000" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sq_miles" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
countryyearGovExpendConsumptionExportsImportsGDP
0Canada20170.3726651.0954750.5828310.6000311.868164
1Canada20160.3648991.0584260.5763940.5757751.814016
2Germany20170.7455792.1120091.9305631.6663483.883870
3Germany20160.7340142.0756151.8449491.5894953.801859
4United Kingdom20170.5495381.8091540.8626290.9331452.818704
5United Kingdom20160.5505961.7723480.8167920.9014942.768241
6United States20172.40574312.0192662.2870713.06995417.348627
7United States20162.40798111.7221332.2199372.93600416.972348
\n", "
" ], "text/plain": [ " country year GovExpend Consumption Exports Imports GDP\n", "0 Canada 2017 0.372665 1.095475 0.582831 0.600031 1.868164\n", "1 Canada 2016 0.364899 1.058426 0.576394 0.575775 1.814016\n", "2 Germany 2017 0.745579 2.112009 1.930563 1.666348 3.883870\n", "3 Germany 2016 0.734014 2.075615 1.844949 1.589495 3.801859\n", "4 United Kingdom 2017 0.549538 1.809154 0.862629 0.933145 2.818704\n", "5 United Kingdom 2016 0.550596 1.772348 0.816792 0.901494 2.768241\n", "6 United States 2017 2.405743 12.019266 2.287071 3.069954 17.348627\n", "7 United States 2016 2.407981 11.722133 2.219937 2.936004 16.972348" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "wdi2016_17.reset_index()" ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "hide-output": false, "slideshow": { "slide_type": "-" } }, "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", "
countryyearGovExpendConsumptionExportsImportsGDPsq_miles
0Canada20170.3726651.0954750.5828310.6000311.8681643.8000
1Canada20160.3648991.0584260.5763940.5757751.8140163.8000
2Germany20170.7455792.1120091.9305631.6663483.8838700.1370
3Germany20160.7340142.0756151.8449491.5894953.8018590.1370
4United Kingdom20170.5495381.8091540.8626290.9331452.8187040.0936
5United Kingdom20160.5505961.7723480.8167920.9014942.7682410.0936
6United States20172.40574312.0192662.2870713.06995417.3486273.8000
7United States20162.40798111.7221332.2199372.93600416.9723483.8000
\n", "
" ], "text/plain": [ " country year GovExpend Consumption Exports Imports \\\n", "0 Canada 2017 0.372665 1.095475 0.582831 0.600031 \n", "1 Canada 2016 0.364899 1.058426 0.576394 0.575775 \n", "2 Germany 2017 0.745579 2.112009 1.930563 1.666348 \n", "3 Germany 2016 0.734014 2.075615 1.844949 1.589495 \n", "4 United Kingdom 2017 0.549538 1.809154 0.862629 0.933145 \n", "5 United Kingdom 2016 0.550596 1.772348 0.816792 0.901494 \n", "6 United States 2017 2.405743 12.019266 2.287071 3.069954 \n", "7 United States 2016 2.407981 11.722133 2.219937 2.936004 \n", "\n", " GDP sq_miles \n", "0 1.868164 3.8000 \n", "1 1.814016 3.8000 \n", "2 3.883870 0.1370 \n", "3 3.801859 0.1370 \n", "4 2.818704 0.0936 \n", "5 2.768241 0.0936 \n", "6 17.348627 3.8000 \n", "7 16.972348 3.8000 " ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pd.merge(wdi2016_17.reset_index(), sq_miles, on=\"country\")" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Multiple Columns\n", "\n", "Sometimes, we need to merge multiple columns.\n", "\n", "For example our `pop` and `wdi2016_17` DataFrames both have observations\n", "organized by country and year.\n", "\n", "To properly merge these datasets, we would need to align the data by\n", "both country and year.\n", "\n", "We pass a list to the `on` argument to accomplish this:" ] }, { "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", "
GovExpendConsumptionExportsImportsGDP
countryyear
Canada20170.3726651.0954750.5828310.6000311.868164
20160.3648991.0584260.5763940.5757751.814016
Germany20170.7455792.1120091.9305631.6663483.883870
20160.7340142.0756151.8449491.5894953.801859
United Kingdom20170.5495381.8091540.8626290.9331452.818704
20160.5505961.7723480.8167920.9014942.768241
United States20172.40574312.0192662.2870713.06995417.348627
20162.40798111.7221332.2199372.93600416.972348
\n", "
" ], "text/plain": [ " GovExpend Consumption Exports Imports GDP\n", "country year \n", "Canada 2017 0.372665 1.095475 0.582831 0.600031 1.868164\n", " 2016 0.364899 1.058426 0.576394 0.575775 1.814016\n", "Germany 2017 0.745579 2.112009 1.930563 1.666348 3.883870\n", " 2016 0.734014 2.075615 1.844949 1.589495 3.801859\n", "United Kingdom 2017 0.549538 1.809154 0.862629 0.933145 2.818704\n", " 2016 0.550596 1.772348 0.816792 0.901494 2.768241\n", "United States 2017 2.405743 12.019266 2.287071 3.069954 17.348627\n", " 2016 2.407981 11.722133 2.219937 2.936004 16.972348" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "wdi2016_17" ] }, { "cell_type": "code", "execution_count": 23, "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", "
Population
countryyear
Canada201736.540268
201636.109487
201535.702908
201435.437435
201335.082954
.........
United States2004292.805298
2003290.107933
2002287.625193
2001284.968955
2000282.162411
\n", "

72 rows × 1 columns

\n", "
" ], "text/plain": [ " Population\n", "country year \n", "Canada 2017 36.540268\n", " 2016 36.109487\n", " 2015 35.702908\n", " 2014 35.437435\n", " 2013 35.082954\n", "... ...\n", "United States 2004 292.805298\n", " 2003 290.107933\n", " 2002 287.625193\n", " 2001 284.968955\n", " 2000 282.162411\n", "\n", "[72 rows x 1 columns]" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pop" ] }, { "cell_type": "code", "execution_count": 24, "metadata": { "hide-output": false, "slideshow": { "slide_type": "-" } }, "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", "
GovExpendConsumptionExportsImportsGDPPopulation
countryyear
Canada20170.3726651.0954750.5828310.6000311.86816436.540268
20160.3648991.0584260.5763940.5757751.81401636.109487
Germany20170.7455792.1120091.9305631.6663483.88387082.657002
20160.7340142.0756151.8449491.5894953.80185982.348669
United Kingdom20170.5495381.8091540.8626290.9331452.81870466.058859
20160.5505961.7723480.8167920.9014942.76824165.595565
United States20172.40574312.0192662.2870713.06995417.348627325.147121
20162.40798111.7221332.2199372.93600416.972348323.071342
\n", "
" ], "text/plain": [ " GovExpend Consumption Exports Imports GDP \\\n", "country year \n", "Canada 2017 0.372665 1.095475 0.582831 0.600031 1.868164 \n", " 2016 0.364899 1.058426 0.576394 0.575775 1.814016 \n", "Germany 2017 0.745579 2.112009 1.930563 1.666348 3.883870 \n", " 2016 0.734014 2.075615 1.844949 1.589495 3.801859 \n", "United Kingdom 2017 0.549538 1.809154 0.862629 0.933145 2.818704 \n", " 2016 0.550596 1.772348 0.816792 0.901494 2.768241 \n", "United States 2017 2.405743 12.019266 2.287071 3.069954 17.348627 \n", " 2016 2.407981 11.722133 2.219937 2.936004 16.972348 \n", "\n", " Population \n", "country year \n", "Canada 2017 36.540268 \n", " 2016 36.109487 \n", "Germany 2017 82.657002 \n", " 2016 82.348669 \n", "United Kingdom 2017 66.058859 \n", " 2016 65.595565 \n", "United States 2017 325.147121 \n", " 2016 323.071342 " ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pd.merge(wdi2016_17, pop, on=[\"country\", \"year\"])" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "Now, we can answer more of our questions from above: What is GDP per capita (per\n", "person) for each country in each year? How about Consumption per person?" ] }, { "cell_type": "code", "execution_count": 25, "metadata": { "hide-output": false, "slideshow": { "slide_type": "-" } }, "outputs": [ { "data": { "text/plain": [ "country year\n", "Canada 2017 0.051126\n", " 2016 0.050237\n", "Germany 2017 0.046988\n", " 2016 0.046168\n", "United Kingdom 2017 0.042670\n", " 2016 0.042202\n", "United States 2017 0.053356\n", " 2016 0.052534\n", "dtype: float64" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "wdi_pop = pd.merge(wdi2016_17, pop, on=[\"country\", \"year\"])\n", "wdi_pop[\"GDP\"] / wdi_pop[\"Population\"]" ] }, { "cell_type": "code", "execution_count": 26, "metadata": { "hide-output": false, "slideshow": { "slide_type": "-" } }, "outputs": [ { "data": { "text/plain": [ "country year\n", "Canada 2017 0.029980\n", " 2016 0.029312\n", "Germany 2017 0.025551\n", " 2016 0.025205\n", "United Kingdom 2017 0.027387\n", " 2016 0.027019\n", "United States 2017 0.036966\n", " 2016 0.036283\n", "dtype: float64" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "wdi_pop[\"Consumption\"] / wdi_pop[\"Population\"]" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "**Exercise 1**\n", "\n", "Use your new `merge` skills to answer the final question from above: What\n", "is the population density of each country? How much does it change over\n", "time?" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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sUJ7GnKPHj20k8V1adiwYfzyyy+89tprqKrKLbfcwn333Vfu6qPq8PLy4tZbb2X//v0MHDiwzsvaXMhjLlrQIxgaQ0urY3nMxbVt4cKFBAUF8fTTT9d42aZWx1f7mAvpPhJCNHvZ2dns27ePY8eOcc899zR2ca5p0n0khGj25syZQ05ODo888ojLJbCiPAkKQohm780332zsIjQZ0n0khBBCI0FBCCGERoKCEEIIjQQFIYQQGgkKQgghNBIUhBBCaCQoCCHqVGxsLIsWLaqXda9Zs4b58+fXej3jx49n//79dVCiyu3fv5/x48fX+3bqkgQFIQTz589nzZo15dJ37drF73//+xqta9KkSTz77LNVrrs+XLx4kfHjx/Pzzz9raYWFhSxYsIA//OEPpKSkALBq1SpuuummBilTUyM3rwkh6pSPj09jF0GTk5PDokWLyM/PZ8GCBbRq1QqwD8Ij3JOgIISottjYWLKzs+nTpw+bN2/GarUyYMAApkyZog3E48gzd+5cYmNjOXnyJCdPniQ+Ph6AZcuW0aZNG86dO8d7771HQkICJpOJG264gaioKK3BttlsfPDBB+zcuROAIUOGoChKtct65coVFixYgJeXFzExMfj6+mrzxo8fz+zZsxk4cCAXL15k+vTp/PGPf2T79u38+OOPBAcHM2nSJCIjI7Vl/vvf//Lee+9x+fJlIiIiGDFiBK+++qq2PwC7d+/mo48+Iisri+uvv56+ffuWK9eOHTvYvHkzly9fpnXr1tx///0MGzbMpWxTpkzh6NGj/O9//yMoKIgnn3yS9u3bs3z5chITE2nXrh1/+MMf6NKlS7Xro7qk+0gIUSMJCQmcO3eO6OhoZs2axaFDh9i6davbvJMmTaJ79+7ceeedrFq1ilWrVhEUFER6ejrz58+nY8eOLFq0iOjoaAoKCnjppZe0hv+LL77gq6++4sknn2ThwoUoisK3335brTJeuHCBefPmERQURHR0tEtAqEhcXBz33HMP//znP4mIiODVV18lPz8fgEuXLrF06VL69evHyy+/zKhRo3jvvfdclj916hTLli1j2LBhvPzyy9x0002sX7/eJc/BgwdZu3Yto0ePZunSpYwePZo1a9Zw+PBhl3wff/wxgwYN4p///CddunTh1VdfZfny5YwYMYIlS5bQqlUrli1bVq26qCk5UhCinnle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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "foo = pd.merge(pop.reset_index(), sq_miles, on=\"country\")\n", "\n", "foo[\"pop_density\"] = foo[\"Population\"] / foo[\"sq_miles\"]\n", "# foo[\"pop_density\"] = foo.eval(\"Population / sq_miles\")\n", "\n", "foo.pivot_table(index=\"year\", columns=\"country\", values=\"pop_density\").plot(kind=\"line\")\n", "# foo.pivot_table(index=\"year\", columns=\"country\", values=\"pop_density\").plot(kind=\"line\")" ] }, { "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", "
sq_miles
country
United States3.8000
Canada3.8000
Germany0.1370
United Kingdom0.0936
Russia6.6000
\n", "
" ], "text/plain": [ " sq_miles\n", "country \n", "United States 3.8000\n", "Canada 3.8000\n", "Germany 0.1370\n", "United Kingdom 0.0936\n", "Russia 6.6000" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sq_miles" ] }, { "cell_type": "code", "execution_count": 27, "metadata": { "slideshow": { "slide_type": "-" } }, "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", "
Population
countryyear
Canada201736.540268
201636.109487
201535.702908
201435.437435
201335.082954
.........
United States2004292.805298
2003290.107933
2002287.625193
2001284.968955
2000282.162411
\n", "

72 rows × 1 columns

\n", "
" ], "text/plain": [ " Population\n", "country year \n", "Canada 2017 36.540268\n", " 2016 36.109487\n", " 2015 35.702908\n", " 2014 35.437435\n", " 2013 35.082954\n", "... ...\n", "United States 2004 292.805298\n", " 2003 290.107933\n", " 2002 287.625193\n", " 2001 284.968955\n", " 2000 282.162411\n", "\n", "[72 rows x 1 columns]" ] }, "execution_count": 27, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pop" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## Arguments to `merge`\n", "\n", "The `pd.merge` function can take many optional arguments.\n", "\n", "We’ll talk about a few of the most commonly-used ones here and refer you\n", "to the\n", "[documentation](https://pandas.pydata.org/pandas-docs/stable/generated/pandas.merge.html#pandas.merge)\n", "for more details.\n", "\n", "We’ll follow the pandas convention and refer to the first argument to\n", "`pd.merge` as `left` and call the second `right`." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "### `on`\n", "\n", "We have already seen this one used before, but we want to point out that on\n", "is optional.\n", "\n", "If nothing is given for this argument, pandas will use **all** columns\n", "in `left` and `right` with the same name.\n", "\n", "In our example, `country` is the only column that appears in both\n", "DataFrames, so it is used for `on` if we don’t pass anything.\n", "\n", "The following two are equivalent." ] }, { "cell_type": "code", "execution_count": 32, "metadata": { "hide-output": false, "slideshow": { "slide_type": "-" } }, "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", "
GovExpendConsumptionExportsImportsGDPsq_miles
country
Canada0.3726651.0954750.5828310.6000311.8681643.8000
Germany0.7455792.1120091.9305631.6663483.8838700.1370
United Kingdom0.5495381.8091540.8626290.9331452.8187040.0936
United States2.40574312.0192662.2870713.06995417.3486273.8000
\n", "
" ], "text/plain": [ " GovExpend Consumption Exports Imports GDP \\\n", "country \n", "Canada 0.372665 1.095475 0.582831 0.600031 1.868164 \n", "Germany 0.745579 2.112009 1.930563 1.666348 3.883870 \n", "United Kingdom 0.549538 1.809154 0.862629 0.933145 2.818704 \n", "United States 2.405743 12.019266 2.287071 3.069954 17.348627 \n", "\n", " sq_miles \n", "country \n", "Canada 3.8000 \n", "Germany 0.1370 \n", "United Kingdom 0.0936 \n", "United States 3.8000 " ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pd.merge(wdi2017, sq_miles, on=\"country\")" ] }, { "cell_type": "code", "execution_count": 33, "metadata": { "hide-output": false, "slideshow": { "slide_type": "-" } }, "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", "
countryGovExpendConsumptionExportsImportsGDPsq_miles
0Canada0.3726651.0954750.5828310.6000311.8681643.8000
1Germany0.7455792.1120091.9305631.6663483.8838700.1370
2United Kingdom0.5495381.8091540.8626290.9331452.8187040.0936
3United States2.40574312.0192662.2870713.06995417.3486273.8000
\n", "
" ], "text/plain": [ " country GovExpend Consumption Exports Imports GDP \\\n", "0 Canada 0.372665 1.095475 0.582831 0.600031 1.868164 \n", "1 Germany 0.745579 2.112009 1.930563 1.666348 3.883870 \n", "2 United Kingdom 0.549538 1.809154 0.862629 0.933145 2.818704 \n", "3 United States 2.405743 12.019266 2.287071 3.069954 17.348627 \n", "\n", " sq_miles \n", "0 3.8000 \n", "1 0.1370 \n", "2 0.0936 \n", "3 3.8000 " ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# if we move index back to columns, the `on` is un-necessary\n", "pd.merge(wdi2017.reset_index(), sq_miles.reset_index())" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "### `left_on`, `right_on`\n", "\n", "Above, we used the `on` argument to identify a column in both `left`\n", "and `right` that was used to align data.\n", "\n", "Sometimes, both DataFrames don’t have the same name for this column.\n", "\n", "In that case, we use the `left_on` and `right_on` arguments, passing\n", "the proper column name(s) to align the data.\n", "\n", "We’ll show you an example below, but it is somewhat silly as our\n", "DataFrames do both have the `country` column." ] }, { "cell_type": "code", "execution_count": 34, "metadata": { "hide-output": false, "slideshow": { "slide_type": "-" } }, "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", "
GovExpendConsumptionExportsImportsGDPsq_miles
country
Canada0.3726651.0954750.5828310.6000311.8681643.8000
Germany0.7455792.1120091.9305631.6663483.8838700.1370
United Kingdom0.5495381.8091540.8626290.9331452.8187040.0936
United States2.40574312.0192662.2870713.06995417.3486273.8000
\n", "
" ], "text/plain": [ " GovExpend Consumption Exports Imports GDP \\\n", "country \n", "Canada 0.372665 1.095475 0.582831 0.600031 1.868164 \n", "Germany 0.745579 2.112009 1.930563 1.666348 3.883870 \n", "United Kingdom 0.549538 1.809154 0.862629 0.933145 2.818704 \n", "United States 2.405743 12.019266 2.287071 3.069954 17.348627 \n", "\n", " sq_miles \n", "country \n", "Canada 3.8000 \n", "Germany 0.1370 \n", "United Kingdom 0.0936 \n", "United States 3.8000 " ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pd.merge(wdi2017, sq_miles, left_on=\"country\", right_on=\"country\")\n", "# pd.merge(wdi2017, sq_miles, left_on=[\"country\", \"year\"], right_on=[\"country\", \"dt\"])" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "### `left_index`, `right_index`\n", "\n", "Sometimes, as in our example, the key used to align data is actually in the\n", "index instead of one of the columns.\n", "\n", "In this case, we can use the `left_index` or `right_index` arguments.\n", "\n", "We should only set these values to a boolean (`True` or `False`).\n", "\n", "Let’s practice with this." ] }, { "cell_type": "code", "execution_count": 38, "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", "
sq_miles
country
United States3.8000
Canada3.8000
Germany0.1370
United Kingdom0.0936
Russia6.6000
\n", "
" ], "text/plain": [ " sq_miles\n", "country \n", "United States 3.8000\n", "Canada 3.8000\n", "Germany 0.1370\n", "United Kingdom 0.0936\n", "Russia 6.6000" ] }, "execution_count": 38, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sq_miles" ] }, { "cell_type": "code", "execution_count": 44, "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", "
countryGovExpendConsumptionExportsImportsGDPsq_miles
0Canada0.3726651.0954750.5828310.6000311.8681643.8000
1Germany0.7455792.1120091.9305631.6663483.8838700.1370
2United Kingdom0.5495381.8091540.8626290.9331452.8187040.0936
3United States2.40574312.0192662.2870713.06995417.3486273.8000
\n", "
" ], "text/plain": [ " country GovExpend Consumption Exports Imports GDP \\\n", "0 Canada 0.372665 1.095475 0.582831 0.600031 1.868164 \n", "1 Germany 0.745579 2.112009 1.930563 1.666348 3.883870 \n", "2 United Kingdom 0.549538 1.809154 0.862629 0.933145 2.818704 \n", "3 United States 2.405743 12.019266 2.287071 3.069954 17.348627 \n", "\n", " sq_miles \n", "0 3.8000 \n", "1 0.1370 \n", "2 0.0936 \n", "3 3.8000 " ] }, "execution_count": 44, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pd.merge(wdi2017.reset_index(), sq_miles, left_on=\"country\", right_index=True) # More important" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Fun trying to break it" ] }, { "cell_type": "code", "execution_count": 40, "metadata": {}, "outputs": [], "source": [ "sq_miles2 = sq_miles.copy()\n", "sq_miles2.index.name = \"test\"" ] }, { "cell_type": "code", "execution_count": 41, "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", "
sq_miles
test
United States3.8000
Canada3.8000
Germany0.1370
United Kingdom0.0936
Russia6.6000
\n", "
" ], "text/plain": [ " sq_miles\n", "test \n", "United States 3.8000\n", "Canada 3.8000\n", "Germany 0.1370\n", "United Kingdom 0.0936\n", "Russia 6.6000" ] }, "execution_count": 41, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sq_miles2" ] }, { "cell_type": "code", "execution_count": 43, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
GovExpendConsumptionExportsImportsGDPsq_miles
country
Canada0.3726651.0954750.5828310.6000311.8681643.8000
Germany0.7455792.1120091.9305631.6663483.8838700.1370
United Kingdom0.5495381.8091540.8626290.9331452.8187040.0936
United States2.40574312.0192662.2870713.06995417.3486273.8000
\n", "
" ], "text/plain": [ " GovExpend Consumption Exports Imports GDP \\\n", "country \n", "Canada 0.372665 1.095475 0.582831 0.600031 1.868164 \n", "Germany 0.745579 2.112009 1.930563 1.666348 3.883870 \n", "United Kingdom 0.549538 1.809154 0.862629 0.933145 2.818704 \n", "United States 2.405743 12.019266 2.287071 3.069954 17.348627 \n", "\n", " sq_miles \n", "country \n", "Canada 3.8000 \n", "Germany 0.1370 \n", "United Kingdom 0.0936 \n", "United States 3.8000 " ] }, "execution_count": 43, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pd.merge(wdi2017, sq_miles2, left_on=\"country\", right_index=True)" ] }, { "cell_type": "code", "execution_count": 37, "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", "
countryGovExpendConsumptionExportsImportsGDP
0Canada0.3726651.0954750.5828310.6000311.868164
1Germany0.7455792.1120091.9305631.6663483.883870
2United Kingdom0.5495381.8091540.8626290.9331452.818704
3United States2.40574312.0192662.2870713.06995417.348627
\n", "
" ], "text/plain": [ " country GovExpend Consumption Exports Imports GDP\n", "0 Canada 0.372665 1.095475 0.582831 0.600031 1.868164\n", "1 Germany 0.745579 2.112009 1.930563 1.666348 3.883870\n", "2 United Kingdom 0.549538 1.809154 0.862629 0.933145 2.818704\n", "3 United States 2.405743 12.019266 2.287071 3.069954 17.348627" ] }, "execution_count": 37, "metadata": {}, "output_type": "execute_result" } ], "source": [ "wdi2017.reset_index()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "hide-output": false, "slideshow": { "slide_type": "-" } }, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "### `how`\n", "\n", "The `how` is perhaps the most powerful, but most conceptually\n", "difficult of the arguments we will cover.\n", "\n", "This argument controls which values from the key column(s) appear in the\n", "output.\n", "\n", "The 4 possible options for this argument are summarized in\n", "the image below.\n", "\n", "\"merge\\_venns.png\"\n", "\n", " \n", "In words, we have:\n", "\n", "- `left`: Default and what we described above. It uses\n", " the keys from the `left` DataFrame. \n", "- `right`: Output will contain all keys from `right`. \n", "- `inner`: The output will only contain keys that appear in *both*\n", " `left` and `right`. \n", "- `outer`: The output will contain any key found in either `left`\n", " or `right`. \n", "\n", "\n", "In addition to the above, we will use the following two DataFrames to\n", "illustrate the `how` option." ] }, { "cell_type": "code", "execution_count": 45, "metadata": { "hide-output": false, "slideshow": { "slide_type": "-" } }, "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", "
GovExpendConsumptionExportsImportsGDP
country
Canada0.3726651.0954750.5828310.6000311.868164
Germany0.7455792.1120091.9305631.6663483.883870
United Kingdom0.5495381.8091540.8626290.9331452.818704
\n", "
" ], "text/plain": [ " GovExpend Consumption Exports Imports GDP\n", "country \n", "Canada 0.372665 1.095475 0.582831 0.600031 1.868164\n", "Germany 0.745579 2.112009 1.930563 1.666348 3.883870\n", "United Kingdom 0.549538 1.809154 0.862629 0.933145 2.818704" ] }, "execution_count": 45, "metadata": {}, "output_type": "execute_result" } ], "source": [ "wdi2017_no_US = wdi2017.drop(\"United States\")\n", "wdi2017_no_US" ] }, { "cell_type": "code", "execution_count": 46, "metadata": { "hide-output": false, "slideshow": { "slide_type": "-" } }, "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", "
sq_miles
country
United States3.8000
Canada3.8000
United Kingdom0.0936
Russia6.6000
\n", "
" ], "text/plain": [ " sq_miles\n", "country \n", "United States 3.8000\n", "Canada 3.8000\n", "United Kingdom 0.0936\n", "Russia 6.6000" ] }, "execution_count": 46, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sq_miles_no_germany = sq_miles.drop(\"Germany\")\n", "sq_miles_no_germany" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "-" } }, "source": [ "Now, let’s see all the possible `how` options." ] }, { "cell_type": "code", "execution_count": 48, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
GovExpendConsumptionExportsImportsGDP
country
Canada0.3726651.0954750.5828310.6000311.868164
Germany0.7455792.1120091.9305631.6663483.883870
United Kingdom0.5495381.8091540.8626290.9331452.818704
United States2.40574312.0192662.2870713.06995417.348627
\n", "
" ], "text/plain": [ " GovExpend Consumption Exports Imports GDP\n", "country \n", "Canada 0.372665 1.095475 0.582831 0.600031 1.868164\n", "Germany 0.745579 2.112009 1.930563 1.666348 3.883870\n", "United Kingdom 0.549538 1.809154 0.862629 0.933145 2.818704\n", "United States 2.405743 12.019266 2.287071 3.069954 17.348627" ] }, "execution_count": 48, "metadata": {}, "output_type": "execute_result" } ], "source": [ "wdi2017" ] }, { "cell_type": "code", "execution_count": 49, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
sq_miles
country
United States3.8000
Canada3.8000
Germany0.1370
United Kingdom0.0936
Russia6.6000
\n", "
" ], "text/plain": [ " sq_miles\n", "country \n", "United States 3.8000\n", "Canada 3.8000\n", "Germany 0.1370\n", "United Kingdom 0.0936\n", "Russia 6.6000" ] }, "execution_count": 49, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sq_miles" ] }, { "cell_type": "code", "execution_count": 47, "metadata": { "hide-output": false, "slideshow": { "slide_type": "-" } }, "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", "
GovExpendConsumptionExportsImportsGDPsq_miles
country
Canada0.3726651.0954750.5828310.6000311.8681643.8000
Germany0.7455792.1120091.9305631.6663483.8838700.1370
United Kingdom0.5495381.8091540.8626290.9331452.8187040.0936
United States2.40574312.0192662.2870713.06995417.3486273.8000
\n", "
" ], "text/plain": [ " GovExpend Consumption Exports Imports GDP \\\n", "country \n", "Canada 0.372665 1.095475 0.582831 0.600031 1.868164 \n", "Germany 0.745579 2.112009 1.930563 1.666348 3.883870 \n", "United Kingdom 0.549538 1.809154 0.862629 0.933145 2.818704 \n", "United States 2.405743 12.019266 2.287071 3.069954 17.348627 \n", "\n", " sq_miles \n", "country \n", "Canada 3.8000 \n", "Germany 0.1370 \n", "United Kingdom 0.0936 \n", "United States 3.8000 " ] }, "execution_count": 47, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# default\n", "pd.merge(wdi2017, sq_miles, on=\"country\", how=\"left\")" ] }, { "cell_type": "code", "execution_count": 50, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
GovExpendConsumptionExportsImportsGDPsq_miles
country
Canada0.3726651.0954750.5828310.6000311.8681643.8000
Germany0.7455792.1120091.9305631.6663483.883870NaN
United Kingdom0.5495381.8091540.8626290.9331452.8187040.0936
United States2.40574312.0192662.2870713.06995417.3486273.8000
\n", "
" ], "text/plain": [ " GovExpend Consumption Exports Imports GDP \\\n", "country \n", "Canada 0.372665 1.095475 0.582831 0.600031 1.868164 \n", "Germany 0.745579 2.112009 1.930563 1.666348 3.883870 \n", "United Kingdom 0.549538 1.809154 0.862629 0.933145 2.818704 \n", "United States 2.405743 12.019266 2.287071 3.069954 17.348627 \n", "\n", " sq_miles \n", "country \n", "Canada 3.8000 \n", "Germany NaN \n", "United Kingdom 0.0936 \n", "United States 3.8000 " ] }, "execution_count": 50, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pd.merge(wdi2017, sq_miles_no_germany, on=\"country\", how=\"left\")" ] }, { "cell_type": "code", "execution_count": 51, "metadata": { "hide-output": false, "slideshow": { "slide_type": "-" } }, "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", "
GovExpendConsumptionExportsImportsGDPsq_miles
country
United States2.40574312.0192662.2870713.06995417.3486273.8000
Canada0.3726651.0954750.5828310.6000311.8681643.8000
Germany0.7455792.1120091.9305631.6663483.8838700.1370
United Kingdom0.5495381.8091540.8626290.9331452.8187040.0936
RussiaNaNNaNNaNNaNNaN6.6000
\n", "
" ], "text/plain": [ " GovExpend Consumption Exports Imports GDP \\\n", "country \n", "United States 2.405743 12.019266 2.287071 3.069954 17.348627 \n", "Canada 0.372665 1.095475 0.582831 0.600031 1.868164 \n", "Germany 0.745579 2.112009 1.930563 1.666348 3.883870 \n", "United Kingdom 0.549538 1.809154 0.862629 0.933145 2.818704 \n", "Russia NaN NaN NaN NaN NaN \n", "\n", " sq_miles \n", "country \n", "United States 3.8000 \n", "Canada 3.8000 \n", "Germany 0.1370 \n", "United Kingdom 0.0936 \n", "Russia 6.6000 " ] }, "execution_count": 51, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# notice ``Russia`` is included\n", "pd.merge(wdi2017, sq_miles, on=\"country\", how=\"right\")" ] }, { "cell_type": "code", "execution_count": 53, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
GovExpendConsumptionExportsImportsGDP
country
Canada0.3726651.0954750.5828310.6000311.868164
Germany0.7455792.1120091.9305631.6663483.883870
United Kingdom0.5495381.8091540.8626290.9331452.818704
\n", "
" ], "text/plain": [ " GovExpend Consumption Exports Imports GDP\n", "country \n", "Canada 0.372665 1.095475 0.582831 0.600031 1.868164\n", "Germany 0.745579 2.112009 1.930563 1.666348 3.883870\n", "United Kingdom 0.549538 1.809154 0.862629 0.933145 2.818704" ] }, "execution_count": 53, "metadata": {}, "output_type": "execute_result" } ], "source": [ "wdi2017_no_US" ] }, { "cell_type": "code", "execution_count": 54, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
sq_miles
country
United States3.8000
Canada3.8000
Germany0.1370
United Kingdom0.0936
Russia6.6000
\n", "
" ], "text/plain": [ " sq_miles\n", "country \n", "United States 3.8000\n", "Canada 3.8000\n", "Germany 0.1370\n", "United Kingdom 0.0936\n", "Russia 6.6000" ] }, "execution_count": 54, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sq_miles\n" ] }, { "cell_type": "code", "execution_count": 52, "metadata": { "hide-output": false, "slideshow": { "slide_type": "-" } }, "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", "
GovExpendConsumptionExportsImportsGDPsq_miles
country
Canada0.3726651.0954750.5828310.6000311.8681643.8000
Germany0.7455792.1120091.9305631.6663483.8838700.1370
United Kingdom0.5495381.8091540.8626290.9331452.8187040.0936
\n", "
" ], "text/plain": [ " GovExpend Consumption Exports Imports GDP sq_miles\n", "country \n", "Canada 0.372665 1.095475 0.582831 0.600031 1.868164 3.8000\n", "Germany 0.745579 2.112009 1.930563 1.666348 3.883870 0.1370\n", "United Kingdom 0.549538 1.809154 0.862629 0.933145 2.818704 0.0936" ] }, "execution_count": 52, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# notice no United States or Russia\n", "pd.merge(wdi2017_no_US, sq_miles, on=\"country\", how=\"inner\")" ] }, { "cell_type": "code", "execution_count": 55, "metadata": { "hide-output": false, "slideshow": { "slide_type": "-" } }, "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", "
GovExpendConsumptionExportsImportsGDPsq_miles
country
Canada0.3726651.0954750.5828310.6000311.8681643.8000
Germany0.7455792.1120091.9305631.6663483.883870NaN
United Kingdom0.5495381.8091540.8626290.9331452.8187040.0936
United StatesNaNNaNNaNNaNNaN3.8000
RussiaNaNNaNNaNNaNNaN6.6000
\n", "
" ], "text/plain": [ " GovExpend Consumption Exports Imports GDP sq_miles\n", "country \n", "Canada 0.372665 1.095475 0.582831 0.600031 1.868164 3.8000\n", "Germany 0.745579 2.112009 1.930563 1.666348 3.883870 NaN\n", "United Kingdom 0.549538 1.809154 0.862629 0.933145 2.818704 0.0936\n", "United States NaN NaN NaN NaN NaN 3.8000\n", "Russia NaN NaN NaN NaN NaN 6.6000" ] }, "execution_count": 55, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# includes all 5, even though they don't all appear in either DataFrame\n", "pd.merge(wdi2017_no_US, sq_miles_no_germany, on=\"country\", how=\"outer\")" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "**Exercise 3**\n", "\n", "Can you pick the correct argument for `how` such that `pd.merge(wdi2017, sq_miles,\n", "how=\"left\")` is equal to `pd.merge(sq_miles, wdi2017, how=XXX)`?" ] }, { "cell_type": "code", "execution_count": 60, "metadata": {}, "outputs": [], "source": [ "pd.merge?" ] }, { "cell_type": "code", "execution_count": 61, "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", "
GovExpendConsumptionExportsImportsGDPsq_miles
country
Canada0.3726651.0954750.5828310.6000311.8681643.8000
Germany0.7455792.1120091.9305631.6663483.8838700.1370
United Kingdom0.5495381.8091540.8626290.9331452.8187040.0936
United States2.40574312.0192662.2870713.06995417.3486273.8000
\n", "
" ], "text/plain": [ " GovExpend Consumption Exports Imports GDP \\\n", "country \n", "Canada 0.372665 1.095475 0.582831 0.600031 1.868164 \n", "Germany 0.745579 2.112009 1.930563 1.666348 3.883870 \n", "United Kingdom 0.549538 1.809154 0.862629 0.933145 2.818704 \n", "United States 2.405743 12.019266 2.287071 3.069954 17.348627 \n", "\n", " sq_miles \n", "country \n", "Canada 3.8000 \n", "Germany 0.1370 \n", "United Kingdom 0.0936 \n", "United States 3.8000 " ] }, "execution_count": 61, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pd.merge(wdi2017, sq_miles, how=\"left\", on=\"country\")" ] }, { "cell_type": "code", "execution_count": 62, "metadata": { "slideshow": { "slide_type": "-" } }, "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", "
sq_milesGovExpendConsumptionExportsImportsGDP
country
Canada3.80000.3726651.0954750.5828310.6000311.868164
Germany0.13700.7455792.1120091.9305631.6663483.883870
United Kingdom0.09360.5495381.8091540.8626290.9331452.818704
United States3.80002.40574312.0192662.2870713.06995417.348627
\n", "
" ], "text/plain": [ " sq_miles GovExpend Consumption Exports Imports \\\n", "country \n", "Canada 3.8000 0.372665 1.095475 0.582831 0.600031 \n", "Germany 0.1370 0.745579 2.112009 1.930563 1.666348 \n", "United Kingdom 0.0936 0.549538 1.809154 0.862629 0.933145 \n", "United States 3.8000 2.405743 12.019266 2.287071 3.069954 \n", "\n", " GDP \n", "country \n", "Canada 1.868164 \n", "Germany 3.883870 \n", "United Kingdom 2.818704 \n", "United States 17.348627 " ] }, "execution_count": 62, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pd.merge(sq_miles, wdi2017, how=\"right\", on=\"country\")" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### `df.merge(df2)`\n", "\n", "Note that the DataFrame type has a `merge` *method*.\n", "\n", "It is the same as the function we have been working with, but passes the\n", "DataFrame before the period as `left`.\n", "\n", "Thus `df.merge(other)` is equivalent to `pd.merge(df, other)`." ] }, { "cell_type": "code", "execution_count": 63, "metadata": { "hide-output": false, "slideshow": { "slide_type": "-" } }, "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", "
GovExpendConsumptionExportsImportsGDPsq_miles
country
United States2.40574312.0192662.2870713.06995417.3486273.8000
Canada0.3726651.0954750.5828310.6000311.8681643.8000
Germany0.7455792.1120091.9305631.6663483.8838700.1370
United Kingdom0.5495381.8091540.8626290.9331452.8187040.0936
RussiaNaNNaNNaNNaNNaN6.6000
\n", "
" ], "text/plain": [ " GovExpend Consumption Exports Imports GDP \\\n", "country \n", "United States 2.405743 12.019266 2.287071 3.069954 17.348627 \n", "Canada 0.372665 1.095475 0.582831 0.600031 1.868164 \n", "Germany 0.745579 2.112009 1.930563 1.666348 3.883870 \n", "United Kingdom 0.549538 1.809154 0.862629 0.933145 2.818704 \n", "Russia NaN NaN NaN NaN NaN \n", "\n", " sq_miles \n", "country \n", "United States 3.8000 \n", "Canada 3.8000 \n", "Germany 0.1370 \n", "United Kingdom 0.0936 \n", "Russia 6.6000 " ] }, "execution_count": 63, "metadata": {}, "output_type": "execute_result" } ], "source": [ "wdi2017.merge(sq_miles, on=\"country\", how=\"right\")" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## `df.join`\n", "\n", "The `join` method for a DataFrame is very similar to the `merge`\n", "method described above, but only allows you to use the index of the\n", "`right` DataFrame as the join key.\n", "\n", "Thus, `left.join(right, on=\"country\")` is equivalent to calling\n", "`pd.merge(left, right, left_on=\"country\", right_index=True)`.\n", "\n", "The implementation of the `join` method calls `merge` internally,\n", "but sets the `left_on` and `right_index` arguments for you.\n", "\n", "You can do anything with `df.join` that you can do with\n", "`df.merge`, but `df.join` is more convenient to use if the keys of `right`\n", "are in the index." ] }, { "cell_type": "code", "execution_count": 64, "metadata": { "hide-output": false, "slideshow": { "slide_type": "-" } }, "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", "
GovExpendConsumptionExportsImportsGDPsq_miles
country
Canada0.3726651.0954750.5828310.6000311.8681643.8000
Germany0.7455792.1120091.9305631.6663483.8838700.1370
United Kingdom0.5495381.8091540.8626290.9331452.8187040.0936
United States2.40574312.0192662.2870713.06995417.3486273.8000
\n", "
" ], "text/plain": [ " GovExpend Consumption Exports Imports GDP \\\n", "country \n", "Canada 0.372665 1.095475 0.582831 0.600031 1.868164 \n", "Germany 0.745579 2.112009 1.930563 1.666348 3.883870 \n", "United Kingdom 0.549538 1.809154 0.862629 0.933145 2.818704 \n", "United States 2.405743 12.019266 2.287071 3.069954 17.348627 \n", "\n", " sq_miles \n", "country \n", "Canada 3.8000 \n", "Germany 0.1370 \n", "United Kingdom 0.0936 \n", "United States 3.8000 " ] }, "execution_count": 64, "metadata": {}, "output_type": "execute_result" } ], "source": [ "wdi2017.join(sq_miles, on=\"country\")" ] }, { "cell_type": "code", "execution_count": 65, "metadata": { "hide-output": false, "slideshow": { "slide_type": "-" } }, "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", "
GovExpendConsumptionExportsImportsGDPsq_miles
country
Canada0.3726651.0954750.5828310.6000311.8681643.8000
Germany0.7455792.1120091.9305631.6663483.8838700.1370
United Kingdom0.5495381.8091540.8626290.9331452.8187040.0936
United States2.40574312.0192662.2870713.06995417.3486273.8000
\n", "
" ], "text/plain": [ " GovExpend Consumption Exports Imports GDP \\\n", "country \n", "Canada 0.372665 1.095475 0.582831 0.600031 1.868164 \n", "Germany 0.745579 2.112009 1.930563 1.666348 3.883870 \n", "United Kingdom 0.549538 1.809154 0.862629 0.933145 2.818704 \n", "United States 2.405743 12.019266 2.287071 3.069954 17.348627 \n", "\n", " sq_miles \n", "country \n", "Canada 3.8000 \n", "Germany 0.1370 \n", "United Kingdom 0.0936 \n", "United States 3.8000 " ] }, "execution_count": 65, "metadata": {}, "output_type": "execute_result" } ], "source": [ "wdi2017.merge(sq_miles, left_on=\"country\", right_index=True)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Case Study\n", "\n", "Let’s put these tools to practice by loading some real datasets and\n", "seeing how these functions can be applied.\n", "\n", "We’ll analyze ratings of books from the website [Goodreads](https://www.goodreads.com/).\n", "\n", "We accessed the data [here](https://github.com/zygmuntz/goodbooks-10k).\n", "\n", "Let’s load it up." ] }, { "cell_type": "code", "execution_count": 66, "metadata": { "hide-output": false, "slideshow": { "slide_type": "-" } }, "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", "
user_idbook_idrating
012585
1240814
222605
3292965
4223183
\n", "
" ], "text/plain": [ " user_id book_id rating\n", "0 1 258 5\n", "1 2 4081 4\n", "2 2 260 5\n", "3 2 9296 5\n", "4 2 2318 3" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "\n", "RangeIndex: 5976479 entries, 0 to 5976478\n", "Data columns (total 3 columns):\n", " # Column Dtype\n", "--- ------ -----\n", " 0 user_id int64\n", " 1 book_id int64\n", " 2 rating int64\n", "dtypes: int64(3)\n", "memory usage: 136.8 MB\n" ] } ], "source": [ "ratings = qeds.data.load(\"goodreads_ratings\")\n", "display(ratings.head())\n", "ratings.info()" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "We can already do some interesting things with just the ratings data.\n", "\n", "Let’s see how many ratings of each number are in our dataset." ] }, { "cell_type": "code", "execution_count": 67, "metadata": { "hide-output": false, "slideshow": { "slide_type": "-" } }, "outputs": [ { "data": { "image/png": "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v/D+7vLly8rLy1N8fLzi4+O1bt067d27V06nU9u2bdOXvvSlcJcYMh9//LF/9duZM2fK5XLp2Wef9e+fM2eO3nvvvXCVF1IvvfSSnn76ablcLs2cOVPf+973FBMTE+6ywu7y5cv6yU9+ovj4eEnSgAEDtHDhwohcHZkA6EJycrJyc3PbvcH/V1VVVadLYfc3LS0tHUJw6dKl8vl8cjqdeu2118JUWXhER0f7/ztgwAD/vW5JGjhwoJqamsJVWsilpaVp586d+s1vfqM1a9ZozZo14S4pbL54jzx48KDDr75NTEzUnTt3wlBV1wiALkycOFEfffTRQwMgKipKPl//X0lj1KhRqqys7HBJv2zZMvl8Pv3iF78IU2WhN3z4cN28eVMpKSmSpDfffLPdw726ujrjfu91QkKCXn/9dZWXl+v111834j3RGafTqZiYGH322We6fv26rFarf19dXZ0GDx4cxuo6RwB0IScnR16v96H7n3zySeXl5YWwovD4xje+offff1+ZmZkd9uXm5uo///mPjh49GobKQs9ut7f7nPv/vsmlzx8S/+/9cJPMmzdPU6ZM0aVLlzR06NBwlxNS//8BiIEDB7bbPnPmjDIyMkJZUkBYDA4ADMUXwQDAUAQAABiKAAAAQxEAAGAoAgAADPVfiCKDsuLxiF0AAAAASUVORK5CYII=\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "ratings[\"rating\"].value_counts().sort_index().plot(kind=\"bar\");" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "Let’s also see how many users have rated `N` books, for all `N`\n", "possible.\n", "\n", "To do this, we will use `value_counts` twice (can you think of why?).\n", "\n", "We will see a more flexible way of performing similar grouped operations in\n", "a future lecture." ] }, { "cell_type": "code", "execution_count": 71, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([ 1, 2, 4, ..., 27329, 33111, 49802])" ] }, "execution_count": 71, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ratings[\"user_id\"].unique()" ] }, { "cell_type": "code", "execution_count": 69, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "30944 200\n", "12874 200\n", "52036 199\n", "28158 199\n", "12381 199\n", " ... \n", "51725 21\n", "32128 21\n", "40753 21\n", "43675 20\n", "34590 19\n", "Name: user_id, Length: 53424, dtype: int64" ] }, "execution_count": 69, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ratings[\"user_id\"].value_counts()" ] }, { "cell_type": "code", "execution_count": 68, "metadata": { "hide-output": false, "slideshow": { "slide_type": "-" } }, "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_ratingsN_users
0191
1201
2213
32213
4235
52411
62513
72623
82734
92826
\n", "
" ], "text/plain": [ " N_ratings N_users\n", "0 19 1\n", "1 20 1\n", "2 21 3\n", "3 22 13\n", "4 23 5\n", "5 24 11\n", "6 25 13\n", "7 26 23\n", "8 27 34\n", "9 28 26" ] }, "execution_count": 68, "metadata": {}, "output_type": "execute_result" } ], "source": [ "users_by_n = (\n", " ratings[\"user_id\"]\n", " .value_counts() # Series. Index: user_id, value: n ratings by user\n", " .value_counts() # Series. Index: n_ratings by user, value: N_users with this many ratings\n", " .sort_index() # Sort our Series by the index (number of ratings)\n", " .reset_index() # Dataframe with columns `index` (from above) and `user_id`\n", " .rename(columns={\"index\": \"N_ratings\", \"user_id\": \"N_users\"})\n", ")\n", "users_by_n.head(10)" ] }, { "cell_type": "code", "execution_count": 72, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
N_ratingsN_users
17119024
1721918
1731927
17419315
1751945
1761955
1771968
1781972
1791993
1802002
\n", "
" ], "text/plain": [ " N_ratings N_users\n", "171 190 24\n", "172 191 8\n", "173 192 7\n", "174 193 15\n", "175 194 5\n", "176 195 5\n", "177 196 8\n", "178 197 2\n", "179 199 3\n", "180 200 2" ] }, "execution_count": 72, "metadata": {}, "output_type": "execute_result" } ], "source": [ "users_by_n.tail(10)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "Let’s look at some statistics on that dataset." ] }, { "cell_type": "code", "execution_count": 75, "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_ratingsN_users
84103927
85104916
87106950
88107961
89108956
90109959
91110964
92111911
93112926
94113926
\n", "
" ], "text/plain": [ " N_ratings N_users\n", "84 103 927\n", "85 104 916\n", "87 106 950\n", "88 107 961\n", "89 108 956\n", "90 109 959\n", "91 110 964\n", "92 111 911\n", "93 112 926\n", "94 113 926" ] }, "execution_count": 75, "metadata": {}, "output_type": "execute_result" } ], "source": [ "users_by_n.loc[users_by_n[\"N_users\"] > 900, :]" ] }, { "cell_type": "code", "execution_count": 73, "metadata": { "hide-output": false, "slideshow": { "slide_type": "-" } }, "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_ratingsN_users
count181.00000181.000000
mean109.01105295.160221
std52.41342309.461848
min19.000001.000000
25%64.0000040.000000
50%109.00000158.000000
75%154.00000538.000000
max200.00000964.000000
\n", "
" ], "text/plain": [ " N_ratings N_users\n", "count 181.00000 181.000000\n", "mean 109.01105 295.160221\n", "std 52.41342 309.461848\n", "min 19.00000 1.000000\n", "25% 64.00000 40.000000\n", "50% 109.00000 158.000000\n", "75% 154.00000 538.000000\n", "max 200.00000 964.000000" ] }, "execution_count": 73, "metadata": {}, "output_type": "execute_result" } ], "source": [ "users_by_n.describe()" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "We can see the same data visually in a box plot." ] }, { "cell_type": "code", "execution_count": 76, "metadata": { "hide-output": false, "slideshow": { "slide_type": "-" } }, "outputs": [ { "data": { "text/plain": [ "N_ratings AxesSubplot(0.125,0.125;0.352273x0.755)\n", "N_users AxesSubplot(0.547727,0.125;0.352273x0.755)\n", "dtype: object" ] }, "execution_count": 76, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "users_by_n.plot(kind=\"box\", subplots=True)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Let’s practice applying the want operator…\n", "\n", "**Want**: Determine whether a relationship between the number of\n", "ratings a user has written and the distribution of the ratings exists. (Maybe we\n", "are an author hoping to inflate our ratings and wonder if we should\n", "target “more experienced” Goodreads users, or focus on newcomers.)\n", "\n", "Let’s start from the result and work our way backwards:\n", "\n", "1. We can answer our question if we have two similar DataFrames: \n", " - All ratings by the `N` (e.g. 5) users with the most ratings \n", " - All ratings by the `N` users with the least number of\n", " ratings \n", "1. To get that, we will need to extract rows of `ratings` with\n", " `user_id` associated with the `N` most and least prolific raters \n", "1. For that, we need the most and least active `user_id`s \n", "1. To get that info, we need a count of how many ratings each user left. \n", " - We can get that with `df[\"user_id\"].value_counts()`, so let’s\n", " start there. " ] }, { "cell_type": "code", "execution_count": 77, "metadata": { "hide-output": false, "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "30944 200\n", "12874 200\n", "52036 199\n", "28158 199\n", "12381 199\n", "Name: user_id, dtype: int64" ] }, "execution_count": 77, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# step 4\n", "n_ratings = ratings[\"user_id\"].value_counts()\n", "n_ratings.head()" ] }, { "cell_type": "code", "execution_count": 78, "metadata": { "hide-output": false, "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "# step 3\n", "N = 5\n", "most_prolific_users = n_ratings.nlargest(5).index.tolist()\n", "least_prolific_users = n_ratings.nsmallest(5).index.tolist()" ] }, { "cell_type": "code", "execution_count": 79, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[30944, 12874, 52036, 28158, 12381]" ] }, "execution_count": 79, "metadata": {}, "output_type": "execute_result" } ], "source": [ "most_prolific_users" ] }, { "cell_type": "code", "execution_count": 80, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[34590, 43675, 51725, 32128, 40753]" ] }, "execution_count": 80, "metadata": {}, "output_type": "execute_result" } ], "source": [ "least_prolific_users" ] }, { "cell_type": "code", "execution_count": 81, "metadata": { "hide-output": false, "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "# step 2\n", "active_ratings = ratings.loc[ratings[\"user_id\"].isin(most_prolific_users), :]\n", "inactive_ratings = ratings.loc[ratings[\"user_id\"].isin(least_prolific_users), :]" ] }, { "cell_type": "code", "execution_count": 82, "metadata": { "hide-output": false, "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 82, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# step 1 -- get the answer!\n", "active_ratings[\"rating\"].value_counts().sort_index().plot(\n", " kind=\"bar\", title=\"Distribution of ratings by most active users\"\n", ")" ] }, { "cell_type": "code", "execution_count": 83, "metadata": { "hide-output": false, "slideshow": { "slide_type": "-" } }, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 83, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "inactive_ratings[\"rating\"].value_counts().sort_index().plot(\n", " kind=\"bar\", title=\"Distribution of ratings by least active users\"\n", ")" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "-" } }, "source": [ "Nice! From the picture above, the new users look much more\n", "likely to leave 5 star ratings than more experienced users." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Book Data\n", "\n", "We know what you are probably thinking: “Isn’t this a lecture on merging?\n", "Why are we only using one dataset?”\n", "\n", "We hear you.\n", "\n", "Let’s also load a dataset containing information on the actual books." ] }, { "cell_type": "code", "execution_count": 84, "metadata": { "hide-output": false, "slideshow": { "slide_type": "-" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "shape: (10000, 3)\n", "dtypes:\n", "book_id int64\n", "authors object\n", "title object\n", "dtype: object\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", "
book_idauthorstitle
01Suzanne CollinsThe Hunger Games (The Hunger Games, #1)
12J.K. Rowling, Mary GrandPréHarry Potter and the Sorcerer's Stone (Harry P...
23Stephenie MeyerTwilight (Twilight, #1)
34Harper LeeTo Kill a Mockingbird
45F. Scott FitzgeraldThe Great Gatsby
\n", "
" ], "text/plain": [ " book_id authors \\\n", "0 1 Suzanne Collins \n", "1 2 J.K. Rowling, Mary GrandPré \n", "2 3 Stephenie Meyer \n", "3 4 Harper Lee \n", "4 5 F. Scott Fitzgerald \n", "\n", " title \n", "0 The Hunger Games (The Hunger Games, #1) \n", "1 Harry Potter and the Sorcerer's Stone (Harry P... \n", "2 Twilight (Twilight, #1) \n", "3 To Kill a Mockingbird \n", "4 The Great Gatsby " ] }, "execution_count": 84, "metadata": {}, "output_type": "execute_result" } ], "source": [ "books = qeds.data.load(\"goodreads_books\")\n", "\n", "# we only need a few of the columns\n", "books = books[[\"book_id\", \"authors\", \"title\"]]\n", "print(\"shape: \", books.shape)\n", "print(\"dtypes:\\n\", books.dtypes, sep=\"\")\n", "books.head()" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "We could do similar interesting things with just the books dataset,\n", "but we will skip it for now and merge them together." ] }, { "cell_type": "code", "execution_count": 87, "metadata": { "hide-output": false, "slideshow": { "slide_type": "-" } }, "outputs": [], "source": [ "rated_books = pd.merge(ratings, books, left_on=\"book_id\", right_on=\"book_id\")" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Now, let’s see which books have been most often rated." ] }, { "cell_type": "code", "execution_count": 88, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
user_idbook_idratingauthorstitle
012585Carlos Ruiz Zafón, Lucia GravesThe Shadow of the Wind (The Cemetery of Forgot...
1112583Carlos Ruiz Zafón, Lucia GravesThe Shadow of the Wind (The Cemetery of Forgot...
21432584Carlos Ruiz Zafón, Lucia GravesThe Shadow of the Wind (The Cemetery of Forgot...
32422585Carlos Ruiz Zafón, Lucia GravesThe Shadow of the Wind (The Cemetery of Forgot...
43252584Carlos Ruiz Zafón, Lucia GravesThe Shadow of the Wind (The Cemetery of Forgot...
..................
59764743677395485L.J. ShenVicious (Sinners of Saint, #1)
59764755067395484L.J. ShenVicious (Sinners of Saint, #1)
59764764521395483L.J. ShenVicious (Sinners of Saint, #1)
59764771287295484L.J. ShenVicious (Sinners of Saint, #1)
59764784635395485L.J. ShenVicious (Sinners of Saint, #1)
\n", "

5976479 rows × 5 columns

\n", "
" ], "text/plain": [ " user_id book_id rating authors \\\n", "0 1 258 5 Carlos Ruiz Zafón, Lucia Graves \n", "1 11 258 3 Carlos Ruiz Zafón, Lucia Graves \n", "2 143 258 4 Carlos Ruiz Zafón, Lucia Graves \n", "3 242 258 5 Carlos Ruiz Zafón, Lucia Graves \n", "4 325 258 4 Carlos Ruiz Zafón, Lucia Graves \n", "... ... ... ... ... \n", "5976474 36773 9548 5 L.J. Shen \n", "5976475 50673 9548 4 L.J. Shen \n", "5976476 45213 9548 3 L.J. Shen \n", "5976477 12872 9548 4 L.J. Shen \n", "5976478 46353 9548 5 L.J. Shen \n", "\n", " title \n", "0 The Shadow of the Wind (The Cemetery of Forgot... \n", "1 The Shadow of the Wind (The Cemetery of Forgot... \n", "2 The Shadow of the Wind (The Cemetery of Forgot... \n", "3 The Shadow of the Wind (The Cemetery of Forgot... \n", "4 The Shadow of the Wind (The Cemetery of Forgot... \n", "... ... \n", "5976474 Vicious (Sinners of Saint, #1) \n", "5976475 Vicious (Sinners of Saint, #1) \n", "5976476 Vicious (Sinners of Saint, #1) \n", "5976477 Vicious (Sinners of Saint, #1) \n", "5976478 Vicious (Sinners of Saint, #1) \n", "\n", "[5976479 rows x 5 columns]" ] }, "execution_count": 88, "metadata": {}, "output_type": "execute_result" } ], "source": [ "rated_books" ] }, { "cell_type": "code", "execution_count": 89, "metadata": { "hide-output": false, "slideshow": { "slide_type": "-" } }, "outputs": [ { "data": { "text/plain": [ "['Harry Potter and the Prisoner of Azkaban (Harry Potter, #3)',\n", " \"Harry Potter and the Sorcerer's Stone (Harry Potter, #1)\",\n", " 'Harry Potter and the Chamber of Secrets (Harry Potter, #2)',\n", " 'The Great Gatsby',\n", " 'To Kill a Mockingbird',\n", " 'The Hobbit',\n", " 'Twilight (Twilight, #1)',\n", " 'The Hunger Games (The Hunger Games, #1)',\n", " 'Catching Fire (The Hunger Games, #2)',\n", " 'Mockingjay (The Hunger Games, #3)']" ] }, "execution_count": 89, "metadata": {}, "output_type": "execute_result" } ], "source": [ "most_rated_books_id = rated_books[\"book_id\"].value_counts().nlargest(10).index\n", "most_rated_books = rated_books.loc[rated_books[\"book_id\"].isin(most_rated_books_id), :]\n", "list(most_rated_books[\"title\"].unique())" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Let’s use our `pivot_table` knowledge to compute the average rating\n", "for each of these books." ] }, { "cell_type": "code", "execution_count": 90, "metadata": { "hide-output": false, "slideshow": { "slide_type": "-" } }, "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", "
rating
title
Catching Fire (The Hunger Games, #2)4.133422
Harry Potter and the Chamber of Secrets (Harry Potter, #2)4.229418
Harry Potter and the Prisoner of Azkaban (Harry Potter, #3)4.418732
Harry Potter and the Sorcerer's Stone (Harry Potter, #1)4.351350
Mockingjay (The Hunger Games, #3)3.853131
The Great Gatsby3.772224
The Hobbit4.148477
The Hunger Games (The Hunger Games, #1)4.279707
To Kill a Mockingbird4.329369
Twilight (Twilight, #1)3.214341
\n", "
" ], "text/plain": [ " rating\n", "title \n", "Catching Fire (The Hunger Games, #2) 4.133422\n", "Harry Potter and the Chamber of Secrets (Harry ... 4.229418\n", "Harry Potter and the Prisoner of Azkaban (Harry... 4.418732\n", "Harry Potter and the Sorcerer's Stone (Harry Po... 4.351350\n", "Mockingjay (The Hunger Games, #3) 3.853131\n", "The Great Gatsby 3.772224\n", "The Hobbit 4.148477\n", "The Hunger Games (The Hunger Games, #1) 4.279707\n", "To Kill a Mockingbird 4.329369\n", "Twilight (Twilight, #1) 3.214341" ] }, "execution_count": 90, "metadata": {}, "output_type": "execute_result" } ], "source": [ "most_rated_books.pivot_table(values=\"rating\", index=\"title\")" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "-" } }, "source": [ "These ratings seem surprisingly low, given that they are the most often\n", "rated books on Goodreads.\n", "\n", "I wonder what the bottom of the distribution looks like..." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "**Exercise 4**\n", "\n", "Repeat the analysis above to determine the average rating for the books with the\n", "*least* number ratings.\n", "\n", "Is there a distinguishable difference in the average rating compared to\n", "the most rated books?\n", "\n", "Did you recognize any of the books?" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Let’s compute the average number of ratings for each book in our sample." ] }, { "cell_type": "code", "execution_count": 94, "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", "
rating
title
The Hunger Games (The Hunger Games, #1)22806
Harry Potter and the Sorcerer's Stone (Harry Potter, #1)21850
To Kill a Mockingbird19088
Twilight (Twilight, #1)16931
The Great Gatsby16604
Catching Fire (The Hunger Games, #2)16549
Mockingjay (The Hunger Games, #3)15953
Harry Potter and the Prisoner of Azkaban (Harry Potter, #3)15855
Harry Potter and the Chamber of Secrets (Harry Potter, #2)15657
The Hobbit15558
\n", "
" ], "text/plain": [ " rating\n", "title \n", "The Hunger Games (The Hunger Games, #1) 22806\n", "Harry Potter and the Sorcerer's Stone (Harry Po... 21850\n", "To Kill a Mockingbird 19088\n", "Twilight (Twilight, #1) 16931\n", "The Great Gatsby 16604\n", "Catching Fire (The Hunger Games, #2) 16549\n", "Mockingjay (The Hunger Games, #3) 15953\n", "Harry Potter and the Prisoner of Azkaban (Harry... 15855\n", "Harry Potter and the Chamber of Secrets (Harry ... 15657\n", "The Hobbit 15558" ] }, "execution_count": 94, "metadata": {}, "output_type": "execute_result" } ], "source": [ "average_ratings = (\n", " rated_books\n", " .pivot_table(values=\"rating\", index=\"title\", aggfunc=len)\n", " .sort_values(by=\"rating\", ascending=False)\n", ")\n", "average_ratings.head(10)" ] }, { "cell_type": "code", "execution_count": 95, "metadata": { "hide-output": false, "slideshow": { "slide_type": "-" } }, "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", "
rating
title
The Complete Calvin and Hobbes4.829876
ESV Study Bible4.818182
Attack of the Deranged Mutant Killer Monster Snow Goons4.768707
The Indispensable Calvin and Hobbes4.766355
The Revenge of the Baby-Sat4.761364
There's Treasure Everywhere: A Calvin and Hobbes Collection4.760456
The Authoritative Calvin and Hobbes: A Calvin and Hobbes Treasury4.757202
It's a Magical World: A Calvin and Hobbes Collection4.747396
Harry Potter Boxed Set, Books 1-5 (Harry Potter, #1-5)4.736842
The Calvin and Hobbes Tenth Anniversary Book4.728528
\n", "
" ], "text/plain": [ " rating\n", "title \n", "The Complete Calvin and Hobbes 4.829876\n", "ESV Study Bible 4.818182\n", "Attack of the Deranged Mutant Killer Monster Sn... 4.768707\n", "The Indispensable Calvin and Hobbes 4.766355\n", "The Revenge of the Baby-Sat 4.761364\n", "There's Treasure Everywhere: A Calvin and Hobbe... 4.760456\n", "The Authoritative Calvin and Hobbes: A Calvin a... 4.757202\n", "It's a Magical World: A Calvin and Hobbes Colle... 4.747396\n", "Harry Potter Boxed Set, Books 1-5 (Harry Potter... 4.736842\n", "The Calvin and Hobbes Tenth Anniversary Book 4.728528" ] }, "execution_count": 95, "metadata": {}, "output_type": "execute_result" } ], "source": [ "average_ratings = (\n", " rated_books\n", " .pivot_table(values=\"rating\", index=\"title\")\n", " .sort_values(by=\"rating\", ascending=False)\n", ")\n", "average_ratings.head(10)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "What does the overall distribution of average ratings look like?" ] }, { "cell_type": "code", "execution_count": 96, "metadata": { "hide-output": false, "slideshow": { "slide_type": "-" } }, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 96, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# plot a kernel density estimate of average ratings\n", "average_ratings.plot.density(xlim=(1, 5))\n", "\n", "# or a histogram\n", "average_ratings.plot.hist(bins=30, xlim=(1, 5))" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "-" } }, "source": [ "It looks like most books have an average rating of just below 4." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Visualizing Merge Operations\n", "\n", "As we did in the [reshape lecture](reshape.ipynb), we will visualize the\n", "various merge operations using artificial DataFrames.\n", "\n", "First, we create some dummy DataFrames." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "hide-output": false, "slideshow": { "slide_type": "-" } }, "outputs": [], "source": [ "dfL = pd.DataFrame(\n", " {\"Key\": [\"A\", \"B\", \"A\", \"C\"], \"C1\":[1, 2, 3, 4], \"C2\": [10, 20, 30, 40]},\n", " index=[\"L1\", \"L2\", \"L3\", \"L4\"]\n", ")[[\"Key\", \"C1\", \"C2\"]]\n", "\n", "print(\"This is dfL: \")\n", "display(dfL)\n", "\n", "dfR = pd.DataFrame(\n", " {\"Key\": [\"A\", \"B\", \"C\", \"D\"], \"C3\": [100, 200, 300, 400]},\n", " index=[\"R1\", \"R2\", \"R3\", \"R4\"]\n", ")[[\"Key\", \"C3\"]]\n", "\n", "print(\"This is dfR:\")\n", "display(dfR)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### `pd.concat`\n", "\n", "Recall that calling `pd.concat(..., axis=0)` will stack DataFrames on top of\n", "one another:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "hide-output": false, "slideshow": { "slide_type": "-" } }, "outputs": [], "source": [ "pd.concat([dfL, dfR], axis=0)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "-" } }, "source": [ "Here’s how we might visualize that.\n", "\n", "\"concat\\_axis0.gif\"\n", "\n", " \n", "We can also set `axis=1` to stack side by side." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "hide-output": false, "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "pd.concat([dfL, dfR], axis=1)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "-" } }, "source": [ "Here’s how we might visualize that.\n", "\n", "\"concat\\_axis1.gif\"" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### `pd.merge`\n", "\n", "The animation below shows a visualization of what happens when we call" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "hide-output": false, "slideshow": { "slide_type": "-" } }, "outputs": [], "source": [ "pd.merge(dfL, dfR, on=\"Key\")" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "-" } }, "source": [ "\"left\\_merge.gif\"\n", "\n", " \n", "Now, let’s focus on what happens when we set `how=\"right\"`.\n", "\n", "Pay special attention to what happens when filling the output value for\n", "the key `A`." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "hide-output": false, "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "pd.merge(dfL, dfR, on=\"Key\", how=\"right\")" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "-" } }, "source": [ "\"right\\_merge.gif\"" ] } ], "metadata": { "celltoolbar": "Slideshow", "date": 1595352472.6962032, "download_nb": false, "filename": "merge.rst", "filename_with_path": "pandas/merge", "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.8.3" }, "title": "Merge" }, "nbformat": 4, "nbformat_minor": 2 }