# The Index

**Prerequisites**

- [Introduction to pandas](https://datascience.quantecon.org/intro.html)  


**Outcomes**

- Understand how the index is used to align data  
- Know how to set and reset the index  
- Understand how to select subsets of data by slicing on index and columns  
- Understand that for DataFrames, the column names also align data  

## Outline

- [The Index](#The-Index)  
  - [So What is this Index?](#So-What-is-this-Index?)  
  - [Setting the Index](#Setting-the-Index)  
  - [Re-setting the Index](#Re-setting-the-Index)  
  - [Choose the Index Carefully](#Choose-the-Index-Carefully)  
  - [Exercises](#Exercises)  


```python
# Uncomment following line to install on colab
! pip install qeds
```

    Requirement already satisfied: qeds in c:\users\asus\anaconda3\lib\site-packages (0.6.2)
    Requirement already satisfied: quandl in c:\users\asus\anaconda3\lib\site-packages (from qeds) (3.5.0)
    Requirement already satisfied: pandas-datareader in c:\users\asus\anaconda3\lib\site-packages (from qeds) (0.8.1)
    Requirement already satisfied: pandas in c:\users\asus\anaconda3\lib\site-packages (from qeds) (0.25.1)
    Requirement already satisfied: statsmodels in c:\users\asus\anaconda3\lib\site-packages (from qeds) (0.10.1)
    Requirement already satisfied: plotly in c:\users\asus\anaconda3\lib\site-packages (from qeds) (4.5.4)
    Requirement already satisfied: numpy in c:\users\asus\anaconda3\lib\site-packages (from qeds) (1.16.5)
    Requirement already satisfied: quantecon in c:\users\asus\anaconda3\lib\site-packages (from qeds) (0.4.6)
    Requirement already satisfied: openpyxl in c:\users\asus\anaconda3\lib\site-packages (from qeds) (3.0.0)
    Requirement already satisfied: pyarrow in c:\users\asus\anaconda3\lib\site-packages (from qeds) (0.16.0)
    Requirement already satisfied: scikit-learn in c:\users\asus\anaconda3\lib\site-packages (from qeds) (0.21.3)
    Requirement already satisfied: scipy in c:\users\asus\anaconda3\lib\site-packages (from qeds) (1.3.1)
    Requirement already satisfied: requests in c:\users\asus\anaconda3\lib\site-packages (from qeds) (2.22.0)
    Requirement already satisfied: matplotlib in c:\users\asus\anaconda3\lib\site-packages (from qeds) (3.1.1)
    Requirement already satisfied: seaborn in c:\users\asus\anaconda3\lib\site-packages (from qeds) (0.9.0)
    Requirement already satisfied: six in c:\users\asus\anaconda3\lib\site-packages (from quandl->qeds) (1.12.0)
    Requirement already satisfied: inflection>=0.3.1 in c:\users\asus\anaconda3\lib\site-packages (from quandl->qeds) (0.3.1)
    Requirement already satisfied: python-dateutil in c:\users\asus\anaconda3\lib\site-packages (from quandl->qeds) (2.8.0)
    Requirement already satisfied: more-itertools in c:\users\asus\anaconda3\lib\site-packages (from quandl->qeds) (7.2.0)
    Requirement already satisfied: lxml in c:\users\asus\anaconda3\lib\site-packages (from pandas-datareader->qeds) (4.4.1)
    Requirement already satisfied: pytz>=2017.2 in c:\users\asus\anaconda3\lib\site-packages (from pandas->qeds) (2019.3)
    Requirement already satisfied: patsy>=0.4.0 in c:\users\asus\anaconda3\lib\site-packages (from statsmodels->qeds) (0.5.1)
    Requirement already satisfied: retrying>=1.3.3 in c:\users\asus\anaconda3\lib\site-packages (from plotly->qeds) (1.3.3)
    Requirement already satisfied: numba>=0.38 in c:\users\asus\anaconda3\lib\site-packages (from quantecon->qeds) (0.45.1)
    Requirement already satisfied: sympy in c:\users\asus\anaconda3\lib\site-packages (from quantecon->qeds) (1.4)
    Requirement already satisfied: jdcal in c:\users\asus\anaconda3\lib\site-packages (from openpyxl->qeds) (1.4.1)
    Requirement already satisfied: et-xmlfile in c:\users\asus\anaconda3\lib\site-packages (from openpyxl->qeds) (1.0.1)
    Requirement already satisfied: joblib>=0.11 in c:\users\asus\anaconda3\lib\site-packages (from scikit-learn->qeds) (0.13.2)
    Requirement already satisfied: chardet<3.1.0,>=3.0.2 in c:\users\asus\anaconda3\lib\site-packages (from requests->qeds) (3.0.4)
    Requirement already satisfied: idna<2.9,>=2.5 in c:\users\asus\anaconda3\lib\site-packages (from requests->qeds) (2.8)
    Requirement already satisfied: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in c:\users\asus\anaconda3\lib\site-packages (from requests->qeds) (1.24.2)
    Requirement already satisfied: certifi>=2017.4.17 in c:\users\asus\anaconda3\lib\site-packages (from requests->qeds) (2019.9.11)
    Requirement already satisfied: cycler>=0.10 in c:\users\asus\anaconda3\lib\site-packages (from matplotlib->qeds) (0.10.0)
    Requirement already satisfied: kiwisolver>=1.0.1 in c:\users\asus\anaconda3\lib\site-packages (from matplotlib->qeds) (1.1.0)
    Requirement already satisfied: pyparsing!=2.0.4,!=2.1.2,!=2.1.6,>=2.0.1 in c:\users\asus\anaconda3\lib\site-packages (from matplotlib->qeds) (2.4.2)
    Requirement already satisfied: llvmlite>=0.29.0dev0 in c:\users\asus\anaconda3\lib\site-packages (from numba>=0.38->quantecon->qeds) (0.29.0)
    Requirement already satisfied: mpmath>=0.19 in c:\users\asus\anaconda3\lib\site-packages (from sympy->quantecon->qeds) (1.1.0)
    Requirement already satisfied: setuptools in c:\users\asus\anaconda3\lib\site-packages (from kiwisolver>=1.0.1->matplotlib->qeds) (41.4.0)



```python
import pandas as pd
import numpy as np
```

## So What is this Index?

Every Series or DataFrame has an index.

We told you that the index was the “row labels” for the data.

This is true, but an index in pandas does much more than label the rows.

The purpose of this lecture is to understand the importance of the index.

The [pandas
documentation](https://pandas.pydata.org/pandas-docs/stable/dsintro.html)
says

> Data alignment is intrinsic. The link between labels and data will
not be broken unless done so explicitly by you.


In practice, the index and column names are used to make sure the data is
properly aligned when operating on multiple DataFrames.

This is a somewhat abstract concept that is best understood by
example…

Let’s begin by loading some data on GDP components that we collected from
the World Bank’s World Development Indicators Dataset.


```python
url = "https://datascience.quantecon.org/assets/data/wdi_data.csv"
df = pd.read_csv(url)
df.info()

df.head()
```

    <class 'pandas.core.frame.DataFrame'>
    RangeIndex: 72 entries, 0 to 71
    Data columns (total 7 columns):
    country        72 non-null object
    year           72 non-null int64
    GovExpend      72 non-null float64
    Consumption    72 non-null float64
    Exports        72 non-null float64
    Imports        72 non-null float64
    GDP            72 non-null float64
    dtypes: float64(5), int64(1), object(1)
    memory usage: 4.1+ KB





<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>country</th>
      <th>year</th>
      <th>GovExpend</th>
      <th>Consumption</th>
      <th>Exports</th>
      <th>Imports</th>
      <th>GDP</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>0</td>
      <td>Canada</td>
      <td>2017</td>
      <td>0.372665</td>
      <td>1.095475</td>
      <td>0.582831</td>
      <td>0.600031</td>
      <td>1.868164</td>
    </tr>
    <tr>
      <td>1</td>
      <td>Canada</td>
      <td>2016</td>
      <td>0.364899</td>
      <td>1.058426</td>
      <td>0.576394</td>
      <td>0.575775</td>
      <td>1.814016</td>
    </tr>
    <tr>
      <td>2</td>
      <td>Canada</td>
      <td>2015</td>
      <td>0.358303</td>
      <td>1.035208</td>
      <td>0.568859</td>
      <td>0.575793</td>
      <td>1.794270</td>
    </tr>
    <tr>
      <td>3</td>
      <td>Canada</td>
      <td>2014</td>
      <td>0.353485</td>
      <td>1.011988</td>
      <td>0.550323</td>
      <td>0.572344</td>
      <td>1.782252</td>
    </tr>
    <tr>
      <td>4</td>
      <td>Canada</td>
      <td>2013</td>
      <td>0.351541</td>
      <td>0.986400</td>
      <td>0.518040</td>
      <td>0.558636</td>
      <td>1.732714</td>
    </tr>
  </tbody>
</table>
</div>



We’ll also extract a couple smaller DataFrames we can use in examples.


```python
df_small = df.head(5)
df_small
```




<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>country</th>
      <th>year</th>
      <th>GovExpend</th>
      <th>Consumption</th>
      <th>Exports</th>
      <th>Imports</th>
      <th>GDP</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>0</td>
      <td>Canada</td>
      <td>2017</td>
      <td>0.372665</td>
      <td>1.095475</td>
      <td>0.582831</td>
      <td>0.600031</td>
      <td>1.868164</td>
    </tr>
    <tr>
      <td>1</td>
      <td>Canada</td>
      <td>2016</td>
      <td>0.364899</td>
      <td>1.058426</td>
      <td>0.576394</td>
      <td>0.575775</td>
      <td>1.814016</td>
    </tr>
    <tr>
      <td>2</td>
      <td>Canada</td>
      <td>2015</td>
      <td>0.358303</td>
      <td>1.035208</td>
      <td>0.568859</td>
      <td>0.575793</td>
      <td>1.794270</td>
    </tr>
    <tr>
      <td>3</td>
      <td>Canada</td>
      <td>2014</td>
      <td>0.353485</td>
      <td>1.011988</td>
      <td>0.550323</td>
      <td>0.572344</td>
      <td>1.782252</td>
    </tr>
    <tr>
      <td>4</td>
      <td>Canada</td>
      <td>2013</td>
      <td>0.351541</td>
      <td>0.986400</td>
      <td>0.518040</td>
      <td>0.558636</td>
      <td>1.732714</td>
    </tr>
  </tbody>
</table>
</div>




```python
df_tiny = df.iloc[[0, 3, 2, 4], :]
df_tiny
```




<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>country</th>
      <th>year</th>
      <th>GovExpend</th>
      <th>Consumption</th>
      <th>Exports</th>
      <th>Imports</th>
      <th>GDP</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>0</td>
      <td>Canada</td>
      <td>2017</td>
      <td>0.372665</td>
      <td>1.095475</td>
      <td>0.582831</td>
      <td>0.600031</td>
      <td>1.868164</td>
    </tr>
    <tr>
      <td>3</td>
      <td>Canada</td>
      <td>2014</td>
      <td>0.353485</td>
      <td>1.011988</td>
      <td>0.550323</td>
      <td>0.572344</td>
      <td>1.782252</td>
    </tr>
    <tr>
      <td>2</td>
      <td>Canada</td>
      <td>2015</td>
      <td>0.358303</td>
      <td>1.035208</td>
      <td>0.568859</td>
      <td>0.575793</td>
      <td>1.794270</td>
    </tr>
    <tr>
      <td>4</td>
      <td>Canada</td>
      <td>2013</td>
      <td>0.351541</td>
      <td>0.986400</td>
      <td>0.518040</td>
      <td>0.558636</td>
      <td>1.732714</td>
    </tr>
  </tbody>
</table>
</div>




```python
im_ex = df_small[["Imports", "Exports"]]
im_ex_copy = im_ex.copy()
im_ex_copy
```




<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>Imports</th>
      <th>Exports</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>0</td>
      <td>0.600031</td>
      <td>0.582831</td>
    </tr>
    <tr>
      <td>1</td>
      <td>0.575775</td>
      <td>0.576394</td>
    </tr>
    <tr>
      <td>2</td>
      <td>0.575793</td>
      <td>0.568859</td>
    </tr>
    <tr>
      <td>3</td>
      <td>0.572344</td>
      <td>0.550323</td>
    </tr>
    <tr>
      <td>4</td>
      <td>0.558636</td>
      <td>0.518040</td>
    </tr>
  </tbody>
</table>
</div>



Observe what happens when we evaluate `im_ex + im_ex_copy`.


```python
im_ex + im_ex_copy
```




<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>Imports</th>
      <th>Exports</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>0</td>
      <td>1.200063</td>
      <td>1.165661</td>
    </tr>
    <tr>
      <td>1</td>
      <td>1.151550</td>
      <td>1.152787</td>
    </tr>
    <tr>
      <td>2</td>
      <td>1.151585</td>
      <td>1.137718</td>
    </tr>
    <tr>
      <td>3</td>
      <td>1.144688</td>
      <td>1.100646</td>
    </tr>
    <tr>
      <td>4</td>
      <td>1.117272</td>
      <td>1.036081</td>
    </tr>
  </tbody>
</table>
</div>



Notice that this operated *elementwise*, meaning that the `+`
operation was applied to each element of `im_ex` and the corresponding
element of `im_ex_copy`.

Let’s take a closer look at `df_tiny`:


```python
df_tiny
```




<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>country</th>
      <th>year</th>
      <th>GovExpend</th>
      <th>Consumption</th>
      <th>Exports</th>
      <th>Imports</th>
      <th>GDP</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>0</td>
      <td>Canada</td>
      <td>2017</td>
      <td>0.372665</td>
      <td>1.095475</td>
      <td>0.582831</td>
      <td>0.600031</td>
      <td>1.868164</td>
    </tr>
    <tr>
      <td>3</td>
      <td>Canada</td>
      <td>2014</td>
      <td>0.353485</td>
      <td>1.011988</td>
      <td>0.550323</td>
      <td>0.572344</td>
      <td>1.782252</td>
    </tr>
    <tr>
      <td>2</td>
      <td>Canada</td>
      <td>2015</td>
      <td>0.358303</td>
      <td>1.035208</td>
      <td>0.568859</td>
      <td>0.575793</td>
      <td>1.794270</td>
    </tr>
    <tr>
      <td>4</td>
      <td>Canada</td>
      <td>2013</td>
      <td>0.351541</td>
      <td>0.986400</td>
      <td>0.518040</td>
      <td>0.558636</td>
      <td>1.732714</td>
    </tr>
  </tbody>
</table>
</div>



Relative to `im_ex` notice a few things:

- The row labeled `1` appears in `im_ex` but not `df_tiny`.  
- For row labels that appear in both, they are not in the same position
  within each DataFrame.  
- Certain columns appear only in `df_tiny`.  
- The `Imports` and `Exports` columns are the 6th and 5th columns of
  `df_tiny` and the 1st and 2nd of `im_ex`, respectively.  


Now, let’s see what happens when we try `df_tiny + im_ex`.


```python
im_ex_tiny = df_tiny + im_ex
im_ex_tiny
```




<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>Consumption</th>
      <th>Exports</th>
      <th>GDP</th>
      <th>GovExpend</th>
      <th>Imports</th>
      <th>country</th>
      <th>year</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>0</td>
      <td>NaN</td>
      <td>1.165661</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>1.200063</td>
      <td>NaN</td>
      <td>NaN</td>
    </tr>
    <tr>
      <td>1</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
    </tr>
    <tr>
      <td>2</td>
      <td>NaN</td>
      <td>1.137718</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>1.151585</td>
      <td>NaN</td>
      <td>NaN</td>
    </tr>
    <tr>
      <td>3</td>
      <td>NaN</td>
      <td>1.100646</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>1.144688</td>
      <td>NaN</td>
      <td>NaN</td>
    </tr>
    <tr>
      <td>4</td>
      <td>NaN</td>
      <td>1.036081</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>1.117272</td>
      <td>NaN</td>
      <td>NaN</td>
    </tr>
  </tbody>
</table>
</div>



Whoa, a lot happened! Let’s break it down.

### Automatic Alignment

For all (row, column) combinations that appear in both DataFrames (e.g.
rows `[1, 3]` and columns `[Imports, Exports]`), the value of `im_ex_tiny`
is equal to `df_tiny.loc[row, col] + im_ex.loc[row, col]`.

This happened even though the rows and columns were not in the same
order.

We refer to this as pandas *aligning* the data for us.

To see how awesome this is, think about how to do something similar in
Excel:

- `df_tiny` and `im_ex` would be in different sheets.  
- The index and column names would be the first column and row in each
  sheet.  
- We would have a third sheet to hold the sum.  
- For each label in the first row and column of *either* the `df_tiny`
  sheet or the `im_ex` sheet we would have to do a `IFELSE` to check
  if the label exists in the other sheet and then a `VLOOKUP` to
  extract the value.  


In pandas, this happens automatically, behind the scenes, and *very
quickly*.

### Handling Missing Data

For all elements in row `1` or columns
`["country", "year", "GovExpend", "Consumption", "GDP"]`,
the value in `im_ex_tiny` is `NaN`.

This is how pandas represents *missing data*.

So, when pandas was trying to look up the values in `df_tiny` and `im_ex`, it could
only find a value in one DataFrame: the other value was missing.

When pandas tries to add a number to something that is missing, it says
that the result is missing (spelled `NaN`).

## Setting the Index

For a DataFrame `df`, the `df.set_index` method allows us to use one
(or more) of the DataFrame’s columns as the index.

Here’s an example.


```python
# first, create the DataFrame
df_year = df.set_index(["year"])
df_year.head()
```




<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>country</th>
      <th>GovExpend</th>
      <th>Consumption</th>
      <th>Exports</th>
      <th>Imports</th>
      <th>GDP</th>
    </tr>
    <tr>
      <th>year</th>
      <th></th>
      <th></th>
      <th></th>
      <th></th>
      <th></th>
      <th></th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>2017</td>
      <td>Canada</td>
      <td>0.372665</td>
      <td>1.095475</td>
      <td>0.582831</td>
      <td>0.600031</td>
      <td>1.868164</td>
    </tr>
    <tr>
      <td>2016</td>
      <td>Canada</td>
      <td>0.364899</td>
      <td>1.058426</td>
      <td>0.576394</td>
      <td>0.575775</td>
      <td>1.814016</td>
    </tr>
    <tr>
      <td>2015</td>
      <td>Canada</td>
      <td>0.358303</td>
      <td>1.035208</td>
      <td>0.568859</td>
      <td>0.575793</td>
      <td>1.794270</td>
    </tr>
    <tr>
      <td>2014</td>
      <td>Canada</td>
      <td>0.353485</td>
      <td>1.011988</td>
      <td>0.550323</td>
      <td>0.572344</td>
      <td>1.782252</td>
    </tr>
    <tr>
      <td>2013</td>
      <td>Canada</td>
      <td>0.351541</td>
      <td>0.986400</td>
      <td>0.518040</td>
      <td>0.558636</td>
      <td>1.732714</td>
    </tr>
  </tbody>
</table>
</div>



Now that the year is on the index, we can use `.loc` to extract all the
data for a specific year.


```python
df_year.loc[2010]
```




<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>country</th>
      <th>GovExpend</th>
      <th>Consumption</th>
      <th>Exports</th>
      <th>Imports</th>
      <th>GDP</th>
    </tr>
    <tr>
      <th>year</th>
      <th></th>
      <th></th>
      <th></th>
      <th></th>
      <th></th>
      <th></th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>2010</td>
      <td>Canada</td>
      <td>0.347332</td>
      <td>0.921952</td>
      <td>0.469949</td>
      <td>0.500341</td>
      <td>1.613543</td>
    </tr>
    <tr>
      <td>2010</td>
      <td>Germany</td>
      <td>0.653386</td>
      <td>1.915481</td>
      <td>1.443735</td>
      <td>1.266126</td>
      <td>3.417095</td>
    </tr>
    <tr>
      <td>2010</td>
      <td>United Kingdom</td>
      <td>0.521146</td>
      <td>1.598563</td>
      <td>0.690824</td>
      <td>0.745065</td>
      <td>2.452900</td>
    </tr>
    <tr>
      <td>2010</td>
      <td>United States</td>
      <td>2.510143</td>
      <td>10.185836</td>
      <td>1.846280</td>
      <td>2.360183</td>
      <td>14.992053</td>
    </tr>
  </tbody>
</table>
</div>



This would be helpful, for example, if we wanted to compute the difference
in the average of all our variables from one year to the next.


```python
df_year.loc[2009].mean() - df_year.loc[2008].mean()
```




    GovExpend      0.033317
    Consumption   -0.042998
    Exports       -0.121425
    Imports       -0.140042
    GDP           -0.182610
    dtype: float64



Notice that pandas did a few things for us.

- After computing `.mean()`, the row labels (index) were the former column names.  
- These column names were used to align data when we wanted asked pandas to
  compute the difference.  


Suppose that someone asked you, “What was the GDP in the US in 2010?”

To compute that using `df_year` you might do something like this:


```python
df_year.loc[df_year["country"] == "United States", "GDP"].loc[2010]
```




    14.992052727



That was a lot of work!

Now, suppose that after seeing you extract that data, your friend asks you
“What about GDP in Germany and the UK in 2010?”

To answer that question, you might write.


```python
df_year.loc[df_year["country"].isin(["United Kingdom", "Germany"]), "GDP"].loc[2010]
```




    year
    2010    3.417095
    2010    2.452900
    Name: GDP, dtype: float64



Notice that this code is similar to the code above, but now provides a result
that is ambiguous.

The two elements in the series both have with label 2010.

How do we know which is which?

We might think that the first value corresponds to the United Kingdom because
that is what we listed first in the call to `isin`, but we would be wrong!

Let’s check.


```python
df_year.loc[2010]
```




<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>country</th>
      <th>GovExpend</th>
      <th>Consumption</th>
      <th>Exports</th>
      <th>Imports</th>
      <th>GDP</th>
    </tr>
    <tr>
      <th>year</th>
      <th></th>
      <th></th>
      <th></th>
      <th></th>
      <th></th>
      <th></th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>2010</td>
      <td>Canada</td>
      <td>0.347332</td>
      <td>0.921952</td>
      <td>0.469949</td>
      <td>0.500341</td>
      <td>1.613543</td>
    </tr>
    <tr>
      <td>2010</td>
      <td>Germany</td>
      <td>0.653386</td>
      <td>1.915481</td>
      <td>1.443735</td>
      <td>1.266126</td>
      <td>3.417095</td>
    </tr>
    <tr>
      <td>2010</td>
      <td>United Kingdom</td>
      <td>0.521146</td>
      <td>1.598563</td>
      <td>0.690824</td>
      <td>0.745065</td>
      <td>2.452900</td>
    </tr>
    <tr>
      <td>2010</td>
      <td>United States</td>
      <td>2.510143</td>
      <td>10.185836</td>
      <td>1.846280</td>
      <td>2.360183</td>
      <td>14.992053</td>
    </tr>
  </tbody>
</table>
</div>



Setting just the year as index has one more potential issue: we will
get data alignment only on the year, which may not be sufficient.

To demonstrate this point, suppose now you are asked to use our WDI dataset
to compute an approximation for net exports and investment in in 2009.

As a seasoned economist, you would remember the expenditure formula for GDP is
written

$$
GDP = Consumption + Investment + GovExpend + Net Exports
$$

which we can rearrange to compute investment as a function of the variables in
our DataFrame…

$$
Investment = GDP - Consumption - GovExpend - Net Exports
$$

Note that we can compute NetExports as `Exports - Imports`.


```python
nx = df_year["Exports"] - df_year["Imports"]
nx.head(19)
```




    year
    2017   -0.017201
    2016    0.000619
    2015   -0.006934
    2014   -0.022021
    2013   -0.040596
    2012   -0.041787
    2011   -0.035878
    2010   -0.030393
    2009    0.000896
    2008    0.004068
    2007    0.032451
    2006    0.053530
    2005    0.072729
    2004    0.091902
    2003    0.097794
    2002    0.121850
    2001    0.122673
    2000    0.118702
    2017    0.264214
    dtype: float64



Now, suppose that we accidentally had a bug in our code that swapped
the data for Canada and Germany’s net exports in 2017.

>**Note**
>
>This example is contrived, but if you were getting unclean data from
some resource or doing more complicated operations, this type of mistake
becomes increasingly likely.


```python
ca17 = nx.iloc[[0]]
g17 = nx.iloc[[18]]
nx.iloc[[0]] = g17
nx.iloc[[18]] = ca17

nx.head(19)
```




    year
    2017    0.264214
    2016    0.000619
    2015   -0.006934
    2014   -0.022021
    2013   -0.040596
    2012   -0.041787
    2011   -0.035878
    2010   -0.030393
    2009    0.000896
    2008    0.004068
    2007    0.032451
    2006    0.053530
    2005    0.072729
    2004    0.091902
    2003    0.097794
    2002    0.121850
    2001    0.122673
    2000    0.118702
    2017   -0.017201
    dtype: float64



Notice that if we now add `nx` to the DataFrame and compute investment
pandas doesn’t complain.


```python
df_year["NetExports"] = nx
df_year["Investment"] = df_year.eval("GDP - Consumption - GovExpend - NetExports")
df_year.head(19)
```




<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>country</th>
      <th>GovExpend</th>
      <th>Consumption</th>
      <th>Exports</th>
      <th>Imports</th>
      <th>GDP</th>
      <th>NetExports</th>
      <th>Investment</th>
    </tr>
    <tr>
      <th>year</th>
      <th></th>
      <th></th>
      <th></th>
      <th></th>
      <th></th>
      <th></th>
      <th></th>
      <th></th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>2017</td>
      <td>Canada</td>
      <td>0.372665</td>
      <td>1.095475</td>
      <td>0.582831</td>
      <td>0.600031</td>
      <td>1.868164</td>
      <td>0.264214</td>
      <td>0.135811</td>
    </tr>
    <tr>
      <td>2016</td>
      <td>Canada</td>
      <td>0.364899</td>
      <td>1.058426</td>
      <td>0.576394</td>
      <td>0.575775</td>
      <td>1.814016</td>
      <td>0.000619</td>
      <td>0.390072</td>
    </tr>
    <tr>
      <td>2015</td>
      <td>Canada</td>
      <td>0.358303</td>
      <td>1.035208</td>
      <td>0.568859</td>
      <td>0.575793</td>
      <td>1.794270</td>
      <td>-0.006934</td>
      <td>0.407692</td>
    </tr>
    <tr>
      <td>2014</td>
      <td>Canada</td>
      <td>0.353485</td>
      <td>1.011988</td>
      <td>0.550323</td>
      <td>0.572344</td>
      <td>1.782252</td>
      <td>-0.022021</td>
      <td>0.438800</td>
    </tr>
    <tr>
      <td>2013</td>
      <td>Canada</td>
      <td>0.351541</td>
      <td>0.986400</td>
      <td>0.518040</td>
      <td>0.558636</td>
      <td>1.732714</td>
      <td>-0.040596</td>
      <td>0.435369</td>
    </tr>
    <tr>
      <td>2012</td>
      <td>Canada</td>
      <td>0.354342</td>
      <td>0.961226</td>
      <td>0.505969</td>
      <td>0.547756</td>
      <td>1.693428</td>
      <td>-0.041787</td>
      <td>0.419647</td>
    </tr>
    <tr>
      <td>2011</td>
      <td>Canada</td>
      <td>0.351887</td>
      <td>0.943145</td>
      <td>0.492349</td>
      <td>0.528227</td>
      <td>1.664240</td>
      <td>-0.035878</td>
      <td>0.405086</td>
    </tr>
    <tr>
      <td>2010</td>
      <td>Canada</td>
      <td>0.347332</td>
      <td>0.921952</td>
      <td>0.469949</td>
      <td>0.500341</td>
      <td>1.613543</td>
      <td>-0.030393</td>
      <td>0.374652</td>
    </tr>
    <tr>
      <td>2009</td>
      <td>Canada</td>
      <td>0.339686</td>
      <td>0.890078</td>
      <td>0.440692</td>
      <td>0.439796</td>
      <td>1.565291</td>
      <td>0.000896</td>
      <td>0.334631</td>
    </tr>
    <tr>
      <td>2008</td>
      <td>Canada</td>
      <td>0.330766</td>
      <td>0.889602</td>
      <td>0.506350</td>
      <td>0.502281</td>
      <td>1.612862</td>
      <td>0.004068</td>
      <td>0.388425</td>
    </tr>
    <tr>
      <td>2007</td>
      <td>Canada</td>
      <td>0.318777</td>
      <td>0.864012</td>
      <td>0.530453</td>
      <td>0.498002</td>
      <td>1.596876</td>
      <td>0.032451</td>
      <td>0.381636</td>
    </tr>
    <tr>
      <td>2006</td>
      <td>Canada</td>
      <td>0.311382</td>
      <td>0.827643</td>
      <td>0.524461</td>
      <td>0.470931</td>
      <td>1.564608</td>
      <td>0.053530</td>
      <td>0.372053</td>
    </tr>
    <tr>
      <td>2005</td>
      <td>Canada</td>
      <td>0.303043</td>
      <td>0.794390</td>
      <td>0.519950</td>
      <td>0.447222</td>
      <td>1.524608</td>
      <td>0.072729</td>
      <td>0.354447</td>
    </tr>
    <tr>
      <td>2004</td>
      <td>Canada</td>
      <td>0.299854</td>
      <td>0.764357</td>
      <td>0.508657</td>
      <td>0.416754</td>
      <td>1.477317</td>
      <td>0.091902</td>
      <td>0.321203</td>
    </tr>
    <tr>
      <td>2003</td>
      <td>Canada</td>
      <td>0.294335</td>
      <td>0.741796</td>
      <td>0.481993</td>
      <td>0.384199</td>
      <td>1.433089</td>
      <td>0.097794</td>
      <td>0.299164</td>
    </tr>
    <tr>
      <td>2002</td>
      <td>Canada</td>
      <td>0.286094</td>
      <td>0.721974</td>
      <td>0.490465</td>
      <td>0.368615</td>
      <td>1.407725</td>
      <td>0.121850</td>
      <td>0.277806</td>
    </tr>
    <tr>
      <td>2001</td>
      <td>Canada</td>
      <td>0.279767</td>
      <td>0.694230</td>
      <td>0.484696</td>
      <td>0.362023</td>
      <td>1.366590</td>
      <td>0.122673</td>
      <td>0.269921</td>
    </tr>
    <tr>
      <td>2000</td>
      <td>Canada</td>
      <td>0.270553</td>
      <td>0.677713</td>
      <td>0.499526</td>
      <td>0.380823</td>
      <td>1.342805</td>
      <td>0.118702</td>
      <td>0.275837</td>
    </tr>
    <tr>
      <td>2017</td>
      <td>Germany</td>
      <td>0.745579</td>
      <td>2.112009</td>
      <td>1.930563</td>
      <td>1.666348</td>
      <td>3.883870</td>
      <td>-0.017201</td>
      <td>1.043482</td>
    </tr>
  </tbody>
</table>
</div>



Because we didn’t also have data alignment on the country, we would have overstated Canada’s investment by 281 billion USD and understated Germany’s by the
same amount.

To make these types operation easier, we need to include both the year
and country in the index…

### Setting a Hierarchical Index

Include multiple columns in the index is advantageous in some situations.

These situations might include:

- When we need more than one piece of information (column) to identify an
  observation (as in the Germany and UK GDP example above)  
- When we need data-alignment by more than one column  


To achieve multiple columns in the index, we pass a list of multiple column
names to `set_index`.


```python
wdi = df.set_index(["country", "year"])
wdi.head(20)
```




<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th></th>
      <th>GovExpend</th>
      <th>Consumption</th>
      <th>Exports</th>
      <th>Imports</th>
      <th>GDP</th>
    </tr>
    <tr>
      <th>country</th>
      <th>year</th>
      <th></th>
      <th></th>
      <th></th>
      <th></th>
      <th></th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td rowspan="18" valign="top">Canada</td>
      <td>2017</td>
      <td>0.372665</td>
      <td>1.095475</td>
      <td>0.582831</td>
      <td>0.600031</td>
      <td>1.868164</td>
    </tr>
    <tr>
      <td>2016</td>
      <td>0.364899</td>
      <td>1.058426</td>
      <td>0.576394</td>
      <td>0.575775</td>
      <td>1.814016</td>
    </tr>
    <tr>
      <td>2015</td>
      <td>0.358303</td>
      <td>1.035208</td>
      <td>0.568859</td>
      <td>0.575793</td>
      <td>1.794270</td>
    </tr>
    <tr>
      <td>2014</td>
      <td>0.353485</td>
      <td>1.011988</td>
      <td>0.550323</td>
      <td>0.572344</td>
      <td>1.782252</td>
    </tr>
    <tr>
      <td>2013</td>
      <td>0.351541</td>
      <td>0.986400</td>
      <td>0.518040</td>
      <td>0.558636</td>
      <td>1.732714</td>
    </tr>
    <tr>
      <td>2012</td>
      <td>0.354342</td>
      <td>0.961226</td>
      <td>0.505969</td>
      <td>0.547756</td>
      <td>1.693428</td>
    </tr>
    <tr>
      <td>2011</td>
      <td>0.351887</td>
      <td>0.943145</td>
      <td>0.492349</td>
      <td>0.528227</td>
      <td>1.664240</td>
    </tr>
    <tr>
      <td>2010</td>
      <td>0.347332</td>
      <td>0.921952</td>
      <td>0.469949</td>
      <td>0.500341</td>
      <td>1.613543</td>
    </tr>
    <tr>
      <td>2009</td>
      <td>0.339686</td>
      <td>0.890078</td>
      <td>0.440692</td>
      <td>0.439796</td>
      <td>1.565291</td>
    </tr>
    <tr>
      <td>2008</td>
      <td>0.330766</td>
      <td>0.889602</td>
      <td>0.506350</td>
      <td>0.502281</td>
      <td>1.612862</td>
    </tr>
    <tr>
      <td>2007</td>
      <td>0.318777</td>
      <td>0.864012</td>
      <td>0.530453</td>
      <td>0.498002</td>
      <td>1.596876</td>
    </tr>
    <tr>
      <td>2006</td>
      <td>0.311382</td>
      <td>0.827643</td>
      <td>0.524461</td>
      <td>0.470931</td>
      <td>1.564608</td>
    </tr>
    <tr>
      <td>2005</td>
      <td>0.303043</td>
      <td>0.794390</td>
      <td>0.519950</td>
      <td>0.447222</td>
      <td>1.524608</td>
    </tr>
    <tr>
      <td>2004</td>
      <td>0.299854</td>
      <td>0.764357</td>
      <td>0.508657</td>
      <td>0.416754</td>
      <td>1.477317</td>
    </tr>
    <tr>
      <td>2003</td>
      <td>0.294335</td>
      <td>0.741796</td>
      <td>0.481993</td>
      <td>0.384199</td>
      <td>1.433089</td>
    </tr>
    <tr>
      <td>2002</td>
      <td>0.286094</td>
      <td>0.721974</td>
      <td>0.490465</td>
      <td>0.368615</td>
      <td>1.407725</td>
    </tr>
    <tr>
      <td>2001</td>
      <td>0.279767</td>
      <td>0.694230</td>
      <td>0.484696</td>
      <td>0.362023</td>
      <td>1.366590</td>
    </tr>
    <tr>
      <td>2000</td>
      <td>0.270553</td>
      <td>0.677713</td>
      <td>0.499526</td>
      <td>0.380823</td>
      <td>1.342805</td>
    </tr>
    <tr>
      <td rowspan="2" valign="top">Germany</td>
      <td>2017</td>
      <td>0.745579</td>
      <td>2.112009</td>
      <td>1.930563</td>
      <td>1.666348</td>
      <td>3.883870</td>
    </tr>
    <tr>
      <td>2016</td>
      <td>0.734014</td>
      <td>2.075615</td>
      <td>1.844949</td>
      <td>1.589495</td>
      <td>3.801859</td>
    </tr>
  </tbody>
</table>
</div>



Notice that in the display above, the row labels seem to have two
*levels* now.

The *outer* (or left-most) level is named `country` and the *inner* (or
right-most) level is named `year`.

When a DataFrame’s index has multiple levels, we (and the pandas documentation)
refer to the DataFrame as having a hierarchical index.

### Slicing a Hierarchical Index

Now, we can answer our friend’s questions in a much more straightforward way.


```python
wdi.loc[("United States", 2010), "GDP"]
```




    14.992052727




```python
wdi.loc[(["United Kingdom", "Germany"], 2010), "GDP"]
```




    country         year
    Germany         2010    3.417095
    United Kingdom  2010    2.452900
    Name: GDP, dtype: float64



As shown above, we can use `wdi.loc` to extract different slices of our
national accounts data.

The rules for using `.loc` with a hierarchically-indexed DataFrame are
similar to the ones we’ve learned for standard DataFrames, but they are a bit
more elaborate as we now have more structure to our data.

**Slicing rules**

pandas slicing reacts differently to `list`s and `tuple`s.

It does this to provide more flexibility to select the
data you want.

`list` in row slicing will be an “or” operation, where it chooses rows
based on whether the index value corresponds to any element of the list.

`tuple` in row slicing will be used to denote a single hierarchical
index and must include a value for each level.

**Row slicing examples**

1. `wdi.loc["United States"]`: all rows where the *outer* most index value is
  equal to `United States`  
1. `wdi.loc[("United States", 2010)]`: all rows where the *outer-most* index value
  is equal to `"United States` and the second level is equal to `2010`  
1. `wdi.loc[["United States", "Canada"]]`: all rows where the *outer-most* index is
  either `"United States"` or `"Canada"`  
1. `wdi.loc[(["United States", "Canada"], [2010, 2011]), :]`: all rows where the
  *outer-most* index is either `"United States` or `"Canada"` AND where the
  second level index is either `2010` or `2011`  
1. `wdi.loc[[("United States", 2010), ("Canada", 2011)], :]`: all rows where the the
  two hierarchical indices are either `("United States", 2010)` or
  `("Canada", 2011)`  


We can also restrict `.loc` to extract certain columns by doing:

1. `wdi.loc[rows, GDP]`: return the rows specified by rows (see rules
  above) and only column named `GDP` (returned object will be a
  Series)  
1. `df.loc[rows, ["GDP", "Consumption"]]`: return the rows specified by rows
  (see rules above) and only columns `GDP` and `Consumption`  

### Alignment with `MultiIndex`

The data alignment features we talked about above also apply to a
`MultiIndex` DataFrame.

### `pd.IndexSlice`

When we want to extract rows for a few values of the outer index and all
values for an inner index level, we can use the convenient
`df.loc[[id11, id22]]` shorthand.

We can use this notation to extract all the data for the United States and
Canada.


```python
wdi.loc[["United States", "Canada"]]
```




<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th></th>
      <th>GovExpend</th>
      <th>Consumption</th>
      <th>Exports</th>
      <th>Imports</th>
      <th>GDP</th>
    </tr>
    <tr>
      <th>country</th>
      <th>year</th>
      <th></th>
      <th></th>
      <th></th>
      <th></th>
      <th></th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td rowspan="18" valign="top">Canada</td>
      <td>2017</td>
      <td>0.372665</td>
      <td>1.095475</td>
      <td>0.582831</td>
      <td>0.600031</td>
      <td>1.868164</td>
    </tr>
    <tr>
      <td>2016</td>
      <td>0.364899</td>
      <td>1.058426</td>
      <td>0.576394</td>
      <td>0.575775</td>
      <td>1.814016</td>
    </tr>
    <tr>
      <td>2015</td>
      <td>0.358303</td>
      <td>1.035208</td>
      <td>0.568859</td>
      <td>0.575793</td>
      <td>1.794270</td>
    </tr>
    <tr>
      <td>2014</td>
      <td>0.353485</td>
      <td>1.011988</td>
      <td>0.550323</td>
      <td>0.572344</td>
      <td>1.782252</td>
    </tr>
    <tr>
      <td>2013</td>
      <td>0.351541</td>
      <td>0.986400</td>
      <td>0.518040</td>
      <td>0.558636</td>
      <td>1.732714</td>
    </tr>
    <tr>
      <td>2012</td>
      <td>0.354342</td>
      <td>0.961226</td>
      <td>0.505969</td>
      <td>0.547756</td>
      <td>1.693428</td>
    </tr>
    <tr>
      <td>2011</td>
      <td>0.351887</td>
      <td>0.943145</td>
      <td>0.492349</td>
      <td>0.528227</td>
      <td>1.664240</td>
    </tr>
    <tr>
      <td>2010</td>
      <td>0.347332</td>
      <td>0.921952</td>
      <td>0.469949</td>
      <td>0.500341</td>
      <td>1.613543</td>
    </tr>
    <tr>
      <td>2009</td>
      <td>0.339686</td>
      <td>0.890078</td>
      <td>0.440692</td>
      <td>0.439796</td>
      <td>1.565291</td>
    </tr>
    <tr>
      <td>2008</td>
      <td>0.330766</td>
      <td>0.889602</td>
      <td>0.506350</td>
      <td>0.502281</td>
      <td>1.612862</td>
    </tr>
    <tr>
      <td>2007</td>
      <td>0.318777</td>
      <td>0.864012</td>
      <td>0.530453</td>
      <td>0.498002</td>
      <td>1.596876</td>
    </tr>
    <tr>
      <td>2006</td>
      <td>0.311382</td>
      <td>0.827643</td>
      <td>0.524461</td>
      <td>0.470931</td>
      <td>1.564608</td>
    </tr>
    <tr>
      <td>2005</td>
      <td>0.303043</td>
      <td>0.794390</td>
      <td>0.519950</td>
      <td>0.447222</td>
      <td>1.524608</td>
    </tr>
    <tr>
      <td>2004</td>
      <td>0.299854</td>
      <td>0.764357</td>
      <td>0.508657</td>
      <td>0.416754</td>
      <td>1.477317</td>
    </tr>
    <tr>
      <td>2003</td>
      <td>0.294335</td>
      <td>0.741796</td>
      <td>0.481993</td>
      <td>0.384199</td>
      <td>1.433089</td>
    </tr>
    <tr>
      <td>2002</td>
      <td>0.286094</td>
      <td>0.721974</td>
      <td>0.490465</td>
      <td>0.368615</td>
      <td>1.407725</td>
    </tr>
    <tr>
      <td>2001</td>
      <td>0.279767</td>
      <td>0.694230</td>
      <td>0.484696</td>
      <td>0.362023</td>
      <td>1.366590</td>
    </tr>
    <tr>
      <td>2000</td>
      <td>0.270553</td>
      <td>0.677713</td>
      <td>0.499526</td>
      <td>0.380823</td>
      <td>1.342805</td>
    </tr>
    <tr>
      <td rowspan="18" valign="top">United States</td>
      <td>2017</td>
      <td>2.405743</td>
      <td>12.019266</td>
      <td>2.287071</td>
      <td>3.069954</td>
      <td>17.348627</td>
    </tr>
    <tr>
      <td>2016</td>
      <td>2.407981</td>
      <td>11.722133</td>
      <td>2.219937</td>
      <td>2.936004</td>
      <td>16.972348</td>
    </tr>
    <tr>
      <td>2015</td>
      <td>2.373130</td>
      <td>11.409800</td>
      <td>2.222228</td>
      <td>2.881337</td>
      <td>16.710459</td>
    </tr>
    <tr>
      <td>2014</td>
      <td>2.334071</td>
      <td>11.000619</td>
      <td>2.209555</td>
      <td>2.732228</td>
      <td>16.242526</td>
    </tr>
    <tr>
      <td>2013</td>
      <td>2.353381</td>
      <td>10.687214</td>
      <td>2.118639</td>
      <td>2.600198</td>
      <td>15.853796</td>
    </tr>
    <tr>
      <td>2012</td>
      <td>2.398873</td>
      <td>10.534042</td>
      <td>2.045509</td>
      <td>2.560677</td>
      <td>15.567038</td>
    </tr>
    <tr>
      <td>2011</td>
      <td>2.434378</td>
      <td>10.378060</td>
      <td>1.978083</td>
      <td>2.493194</td>
      <td>15.224555</td>
    </tr>
    <tr>
      <td>2010</td>
      <td>2.510143</td>
      <td>10.185836</td>
      <td>1.846280</td>
      <td>2.360183</td>
      <td>14.992053</td>
    </tr>
    <tr>
      <td>2009</td>
      <td>2.507390</td>
      <td>10.010687</td>
      <td>1.646432</td>
      <td>2.086299</td>
      <td>14.617299</td>
    </tr>
    <tr>
      <td>2008</td>
      <td>2.407771</td>
      <td>10.137847</td>
      <td>1.797347</td>
      <td>2.400349</td>
      <td>14.997756</td>
    </tr>
    <tr>
      <td>2007</td>
      <td>2.351987</td>
      <td>10.159387</td>
      <td>1.701096</td>
      <td>2.455016</td>
      <td>15.018268</td>
    </tr>
    <tr>
      <td>2006</td>
      <td>2.314957</td>
      <td>9.938503</td>
      <td>1.564920</td>
      <td>2.395189</td>
      <td>14.741688</td>
    </tr>
    <tr>
      <td>2005</td>
      <td>2.287022</td>
      <td>9.643098</td>
      <td>1.431205</td>
      <td>2.246246</td>
      <td>14.332500</td>
    </tr>
    <tr>
      <td>2004</td>
      <td>2.267999</td>
      <td>9.311431</td>
      <td>1.335978</td>
      <td>2.108585</td>
      <td>13.846058</td>
    </tr>
    <tr>
      <td>2003</td>
      <td>2.233519</td>
      <td>8.974708</td>
      <td>1.218199</td>
      <td>1.892825</td>
      <td>13.339312</td>
    </tr>
    <tr>
      <td>2002</td>
      <td>2.193188</td>
      <td>8.698306</td>
      <td>1.192180</td>
      <td>1.804105</td>
      <td>12.968263</td>
    </tr>
    <tr>
      <td>2001</td>
      <td>2.112038</td>
      <td>8.480461</td>
      <td>1.213253</td>
      <td>1.740797</td>
      <td>12.746262</td>
    </tr>
    <tr>
      <td>2000</td>
      <td>2.040500</td>
      <td>8.272097</td>
      <td>1.287739</td>
      <td>1.790995</td>
      <td>12.620268</td>
    </tr>
  </tbody>
</table>
</div>



However, suppose we wanted to extract the data for all countries, but only the
years 2005, 2007, and 2009.

We cannot do this using `wdi.loc` because the year is on the second level,
not outer-most level of our index.

To get around this limitation, we can use the `pd.IndexSlice` helper.

Here’s an example.


```python
wdi.loc[pd.IndexSlice[:, [2005, 2007, 2009]], :]
```




<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th></th>
      <th>GovExpend</th>
      <th>Consumption</th>
      <th>Exports</th>
      <th>Imports</th>
      <th>GDP</th>
    </tr>
    <tr>
      <th>country</th>
      <th>year</th>
      <th></th>
      <th></th>
      <th></th>
      <th></th>
      <th></th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td rowspan="3" valign="top">Canada</td>
      <td>2009</td>
      <td>0.339686</td>
      <td>0.890078</td>
      <td>0.440692</td>
      <td>0.439796</td>
      <td>1.565291</td>
    </tr>
    <tr>
      <td>2007</td>
      <td>0.318777</td>
      <td>0.864012</td>
      <td>0.530453</td>
      <td>0.498002</td>
      <td>1.596876</td>
    </tr>
    <tr>
      <td>2005</td>
      <td>0.303043</td>
      <td>0.794390</td>
      <td>0.519950</td>
      <td>0.447222</td>
      <td>1.524608</td>
    </tr>
    <tr>
      <td rowspan="3" valign="top">Germany</td>
      <td>2009</td>
      <td>0.645023</td>
      <td>1.908393</td>
      <td>1.260525</td>
      <td>1.121914</td>
      <td>3.283144</td>
    </tr>
    <tr>
      <td>2007</td>
      <td>0.605624</td>
      <td>1.894219</td>
      <td>1.442436</td>
      <td>1.213835</td>
      <td>3.441356</td>
    </tr>
    <tr>
      <td>2005</td>
      <td>0.591184</td>
      <td>1.866253</td>
      <td>1.175200</td>
      <td>1.028094</td>
      <td>3.213777</td>
    </tr>
    <tr>
      <td rowspan="3" valign="top">United Kingdom</td>
      <td>2009</td>
      <td>0.519716</td>
      <td>1.587152</td>
      <td>0.653830</td>
      <td>0.689011</td>
      <td>2.411632</td>
    </tr>
    <tr>
      <td>2007</td>
      <td>0.504549</td>
      <td>1.644789</td>
      <td>0.710200</td>
      <td>0.767699</td>
      <td>2.527327</td>
    </tr>
    <tr>
      <td>2005</td>
      <td>0.490806</td>
      <td>1.578914</td>
      <td>0.640088</td>
      <td>0.715951</td>
      <td>2.403352</td>
    </tr>
    <tr>
      <td rowspan="3" valign="top">United States</td>
      <td>2009</td>
      <td>2.507390</td>
      <td>10.010687</td>
      <td>1.646432</td>
      <td>2.086299</td>
      <td>14.617299</td>
    </tr>
    <tr>
      <td>2007</td>
      <td>2.351987</td>
      <td>10.159387</td>
      <td>1.701096</td>
      <td>2.455016</td>
      <td>15.018268</td>
    </tr>
    <tr>
      <td>2005</td>
      <td>2.287022</td>
      <td>9.643098</td>
      <td>1.431205</td>
      <td>2.246246</td>
      <td>14.332500</td>
    </tr>
  </tbody>
</table>
</div>



Notice that the `:` in the first part of `[:, ["A", "D"]]`
instructed pandas to give us rows for all values of the outer most index
level and that the `:` just before `]` said grab all the columns.

### Multi-index Columns

The functionality of `MultiIndex` also applies to the column names.

Let’s see how it works.


```python
wdiT = wdi.T  # .T means "transpose" or "swap rows and columns"
wdiT
```




<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead tr th {
        text-align: left;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr>
      <th>country</th>
      <th colspan="10" halign="left">Canada</th>
      <th>...</th>
      <th colspan="10" halign="left">United States</th>
    </tr>
    <tr>
      <th>year</th>
      <th>2017</th>
      <th>2016</th>
      <th>2015</th>
      <th>2014</th>
      <th>2013</th>
      <th>2012</th>
      <th>2011</th>
      <th>2010</th>
      <th>2009</th>
      <th>2008</th>
      <th>...</th>
      <th>2009</th>
      <th>2008</th>
      <th>2007</th>
      <th>2006</th>
      <th>2005</th>
      <th>2004</th>
      <th>2003</th>
      <th>2002</th>
      <th>2001</th>
      <th>2000</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>GovExpend</td>
      <td>0.372665</td>
      <td>0.364899</td>
      <td>0.358303</td>
      <td>0.353485</td>
      <td>0.351541</td>
      <td>0.354342</td>
      <td>0.351887</td>
      <td>0.347332</td>
      <td>0.339686</td>
      <td>0.330766</td>
      <td>...</td>
      <td>2.507390</td>
      <td>2.407771</td>
      <td>2.351987</td>
      <td>2.314957</td>
      <td>2.287022</td>
      <td>2.267999</td>
      <td>2.233519</td>
      <td>2.193188</td>
      <td>2.112038</td>
      <td>2.040500</td>
    </tr>
    <tr>
      <td>Consumption</td>
      <td>1.095475</td>
      <td>1.058426</td>
      <td>1.035208</td>
      <td>1.011988</td>
      <td>0.986400</td>
      <td>0.961226</td>
      <td>0.943145</td>
      <td>0.921952</td>
      <td>0.890078</td>
      <td>0.889602</td>
      <td>...</td>
      <td>10.010687</td>
      <td>10.137847</td>
      <td>10.159387</td>
      <td>9.938503</td>
      <td>9.643098</td>
      <td>9.311431</td>
      <td>8.974708</td>
      <td>8.698306</td>
      <td>8.480461</td>
      <td>8.272097</td>
    </tr>
    <tr>
      <td>Exports</td>
      <td>0.582831</td>
      <td>0.576394</td>
      <td>0.568859</td>
      <td>0.550323</td>
      <td>0.518040</td>
      <td>0.505969</td>
      <td>0.492349</td>
      <td>0.469949</td>
      <td>0.440692</td>
      <td>0.506350</td>
      <td>...</td>
      <td>1.646432</td>
      <td>1.797347</td>
      <td>1.701096</td>
      <td>1.564920</td>
      <td>1.431205</td>
      <td>1.335978</td>
      <td>1.218199</td>
      <td>1.192180</td>
      <td>1.213253</td>
      <td>1.287739</td>
    </tr>
    <tr>
      <td>Imports</td>
      <td>0.600031</td>
      <td>0.575775</td>
      <td>0.575793</td>
      <td>0.572344</td>
      <td>0.558636</td>
      <td>0.547756</td>
      <td>0.528227</td>
      <td>0.500341</td>
      <td>0.439796</td>
      <td>0.502281</td>
      <td>...</td>
      <td>2.086299</td>
      <td>2.400349</td>
      <td>2.455016</td>
      <td>2.395189</td>
      <td>2.246246</td>
      <td>2.108585</td>
      <td>1.892825</td>
      <td>1.804105</td>
      <td>1.740797</td>
      <td>1.790995</td>
    </tr>
    <tr>
      <td>GDP</td>
      <td>1.868164</td>
      <td>1.814016</td>
      <td>1.794270</td>
      <td>1.782252</td>
      <td>1.732714</td>
      <td>1.693428</td>
      <td>1.664240</td>
      <td>1.613543</td>
      <td>1.565291</td>
      <td>1.612862</td>
      <td>...</td>
      <td>14.617299</td>
      <td>14.997756</td>
      <td>15.018268</td>
      <td>14.741688</td>
      <td>14.332500</td>
      <td>13.846058</td>
      <td>13.339312</td>
      <td>12.968263</td>
      <td>12.746262</td>
      <td>12.620268</td>
    </tr>
  </tbody>
</table>
<p>5 rows × 72 columns</p>
</div>



Notice that `wdiT` seems to have two levels of names for the columns.

The same logic laid out in the above row slicing rules applies when we
have a hierarchical index for column names.


```python
wdiT.loc[:, "United States"]
```




<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th>year</th>
      <th>2017</th>
      <th>2016</th>
      <th>2015</th>
      <th>2014</th>
      <th>2013</th>
      <th>2012</th>
      <th>2011</th>
      <th>2010</th>
      <th>2009</th>
      <th>2008</th>
      <th>2007</th>
      <th>2006</th>
      <th>2005</th>
      <th>2004</th>
      <th>2003</th>
      <th>2002</th>
      <th>2001</th>
      <th>2000</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>GovExpend</td>
      <td>2.405743</td>
      <td>2.407981</td>
      <td>2.373130</td>
      <td>2.334071</td>
      <td>2.353381</td>
      <td>2.398873</td>
      <td>2.434378</td>
      <td>2.510143</td>
      <td>2.507390</td>
      <td>2.407771</td>
      <td>2.351987</td>
      <td>2.314957</td>
      <td>2.287022</td>
      <td>2.267999</td>
      <td>2.233519</td>
      <td>2.193188</td>
      <td>2.112038</td>
      <td>2.040500</td>
    </tr>
    <tr>
      <td>Consumption</td>
      <td>12.019266</td>
      <td>11.722133</td>
      <td>11.409800</td>
      <td>11.000619</td>
      <td>10.687214</td>
      <td>10.534042</td>
      <td>10.378060</td>
      <td>10.185836</td>
      <td>10.010687</td>
      <td>10.137847</td>
      <td>10.159387</td>
      <td>9.938503</td>
      <td>9.643098</td>
      <td>9.311431</td>
      <td>8.974708</td>
      <td>8.698306</td>
      <td>8.480461</td>
      <td>8.272097</td>
    </tr>
    <tr>
      <td>Exports</td>
      <td>2.287071</td>
      <td>2.219937</td>
      <td>2.222228</td>
      <td>2.209555</td>
      <td>2.118639</td>
      <td>2.045509</td>
      <td>1.978083</td>
      <td>1.846280</td>
      <td>1.646432</td>
      <td>1.797347</td>
      <td>1.701096</td>
      <td>1.564920</td>
      <td>1.431205</td>
      <td>1.335978</td>
      <td>1.218199</td>
      <td>1.192180</td>
      <td>1.213253</td>
      <td>1.287739</td>
    </tr>
    <tr>
      <td>Imports</td>
      <td>3.069954</td>
      <td>2.936004</td>
      <td>2.881337</td>
      <td>2.732228</td>
      <td>2.600198</td>
      <td>2.560677</td>
      <td>2.493194</td>
      <td>2.360183</td>
      <td>2.086299</td>
      <td>2.400349</td>
      <td>2.455016</td>
      <td>2.395189</td>
      <td>2.246246</td>
      <td>2.108585</td>
      <td>1.892825</td>
      <td>1.804105</td>
      <td>1.740797</td>
      <td>1.790995</td>
    </tr>
    <tr>
      <td>GDP</td>
      <td>17.348627</td>
      <td>16.972348</td>
      <td>16.710459</td>
      <td>16.242526</td>
      <td>15.853796</td>
      <td>15.567038</td>
      <td>15.224555</td>
      <td>14.992053</td>
      <td>14.617299</td>
      <td>14.997756</td>
      <td>15.018268</td>
      <td>14.741688</td>
      <td>14.332500</td>
      <td>13.846058</td>
      <td>13.339312</td>
      <td>12.968263</td>
      <td>12.746262</td>
      <td>12.620268</td>
    </tr>
  </tbody>
</table>
</div>




```python
wdiT.loc[:, ["United States", "Canada"]]
```




<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead tr th {
        text-align: left;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr>
      <th>country</th>
      <th colspan="10" halign="left">Canada</th>
      <th>...</th>
      <th colspan="10" halign="left">United States</th>
    </tr>
    <tr>
      <th>year</th>
      <th>2017</th>
      <th>2016</th>
      <th>2015</th>
      <th>2014</th>
      <th>2013</th>
      <th>2012</th>
      <th>2011</th>
      <th>2010</th>
      <th>2009</th>
      <th>2008</th>
      <th>...</th>
      <th>2009</th>
      <th>2008</th>
      <th>2007</th>
      <th>2006</th>
      <th>2005</th>
      <th>2004</th>
      <th>2003</th>
      <th>2002</th>
      <th>2001</th>
      <th>2000</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>GovExpend</td>
      <td>0.372665</td>
      <td>0.364899</td>
      <td>0.358303</td>
      <td>0.353485</td>
      <td>0.351541</td>
      <td>0.354342</td>
      <td>0.351887</td>
      <td>0.347332</td>
      <td>0.339686</td>
      <td>0.330766</td>
      <td>...</td>
      <td>2.507390</td>
      <td>2.407771</td>
      <td>2.351987</td>
      <td>2.314957</td>
      <td>2.287022</td>
      <td>2.267999</td>
      <td>2.233519</td>
      <td>2.193188</td>
      <td>2.112038</td>
      <td>2.040500</td>
    </tr>
    <tr>
      <td>Consumption</td>
      <td>1.095475</td>
      <td>1.058426</td>
      <td>1.035208</td>
      <td>1.011988</td>
      <td>0.986400</td>
      <td>0.961226</td>
      <td>0.943145</td>
      <td>0.921952</td>
      <td>0.890078</td>
      <td>0.889602</td>
      <td>...</td>
      <td>10.010687</td>
      <td>10.137847</td>
      <td>10.159387</td>
      <td>9.938503</td>
      <td>9.643098</td>
      <td>9.311431</td>
      <td>8.974708</td>
      <td>8.698306</td>
      <td>8.480461</td>
      <td>8.272097</td>
    </tr>
    <tr>
      <td>Exports</td>
      <td>0.582831</td>
      <td>0.576394</td>
      <td>0.568859</td>
      <td>0.550323</td>
      <td>0.518040</td>
      <td>0.505969</td>
      <td>0.492349</td>
      <td>0.469949</td>
      <td>0.440692</td>
      <td>0.506350</td>
      <td>...</td>
      <td>1.646432</td>
      <td>1.797347</td>
      <td>1.701096</td>
      <td>1.564920</td>
      <td>1.431205</td>
      <td>1.335978</td>
      <td>1.218199</td>
      <td>1.192180</td>
      <td>1.213253</td>
      <td>1.287739</td>
    </tr>
    <tr>
      <td>Imports</td>
      <td>0.600031</td>
      <td>0.575775</td>
      <td>0.575793</td>
      <td>0.572344</td>
      <td>0.558636</td>
      <td>0.547756</td>
      <td>0.528227</td>
      <td>0.500341</td>
      <td>0.439796</td>
      <td>0.502281</td>
      <td>...</td>
      <td>2.086299</td>
      <td>2.400349</td>
      <td>2.455016</td>
      <td>2.395189</td>
      <td>2.246246</td>
      <td>2.108585</td>
      <td>1.892825</td>
      <td>1.804105</td>
      <td>1.740797</td>
      <td>1.790995</td>
    </tr>
    <tr>
      <td>GDP</td>
      <td>1.868164</td>
      <td>1.814016</td>
      <td>1.794270</td>
      <td>1.782252</td>
      <td>1.732714</td>
      <td>1.693428</td>
      <td>1.664240</td>
      <td>1.613543</td>
      <td>1.565291</td>
      <td>1.612862</td>
      <td>...</td>
      <td>14.617299</td>
      <td>14.997756</td>
      <td>15.018268</td>
      <td>14.741688</td>
      <td>14.332500</td>
      <td>13.846058</td>
      <td>13.339312</td>
      <td>12.968263</td>
      <td>12.746262</td>
      <td>12.620268</td>
    </tr>
  </tbody>
</table>
<p>5 rows × 36 columns</p>
</div>




```python
wdiT.loc[:, (["United States", "Canada"], 2010)]
```




<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead tr th {
        text-align: left;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr>
      <th>country</th>
      <th>Canada</th>
      <th>United States</th>
    </tr>
    <tr>
      <th>year</th>
      <th>2010</th>
      <th>2010</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>GovExpend</td>
      <td>0.347332</td>
      <td>2.510143</td>
    </tr>
    <tr>
      <td>Consumption</td>
      <td>0.921952</td>
      <td>10.185836</td>
    </tr>
    <tr>
      <td>Exports</td>
      <td>0.469949</td>
      <td>1.846280</td>
    </tr>
    <tr>
      <td>Imports</td>
      <td>0.500341</td>
      <td>2.360183</td>
    </tr>
    <tr>
      <td>GDP</td>
      <td>1.613543</td>
      <td>14.992053</td>
    </tr>
  </tbody>
</table>
</div>



## Re-setting the Index

The `df.reset_index` method will move one or more level of the index
back into the DataFrame as a normal column.

With no additional arguments, it moves all levels out of the index and
sets the index of the returned DataFrame to the default of
`range(df.shape[0])`.


```python
wdi.reset_index()
```




<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>country</th>
      <th>year</th>
      <th>GovExpend</th>
      <th>Consumption</th>
      <th>Exports</th>
      <th>Imports</th>
      <th>GDP</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>0</td>
      <td>Canada</td>
      <td>2017</td>
      <td>0.372665</td>
      <td>1.095475</td>
      <td>0.582831</td>
      <td>0.600031</td>
      <td>1.868164</td>
    </tr>
    <tr>
      <td>1</td>
      <td>Canada</td>
      <td>2016</td>
      <td>0.364899</td>
      <td>1.058426</td>
      <td>0.576394</td>
      <td>0.575775</td>
      <td>1.814016</td>
    </tr>
    <tr>
      <td>2</td>
      <td>Canada</td>
      <td>2015</td>
      <td>0.358303</td>
      <td>1.035208</td>
      <td>0.568859</td>
      <td>0.575793</td>
      <td>1.794270</td>
    </tr>
    <tr>
      <td>3</td>
      <td>Canada</td>
      <td>2014</td>
      <td>0.353485</td>
      <td>1.011988</td>
      <td>0.550323</td>
      <td>0.572344</td>
      <td>1.782252</td>
    </tr>
    <tr>
      <td>4</td>
      <td>Canada</td>
      <td>2013</td>
      <td>0.351541</td>
      <td>0.986400</td>
      <td>0.518040</td>
      <td>0.558636</td>
      <td>1.732714</td>
    </tr>
    <tr>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
    </tr>
    <tr>
      <td>67</td>
      <td>United States</td>
      <td>2004</td>
      <td>2.267999</td>
      <td>9.311431</td>
      <td>1.335978</td>
      <td>2.108585</td>
      <td>13.846058</td>
    </tr>
    <tr>
      <td>68</td>
      <td>United States</td>
      <td>2003</td>
      <td>2.233519</td>
      <td>8.974708</td>
      <td>1.218199</td>
      <td>1.892825</td>
      <td>13.339312</td>
    </tr>
    <tr>
      <td>69</td>
      <td>United States</td>
      <td>2002</td>
      <td>2.193188</td>
      <td>8.698306</td>
      <td>1.192180</td>
      <td>1.804105</td>
      <td>12.968263</td>
    </tr>
    <tr>
      <td>70</td>
      <td>United States</td>
      <td>2001</td>
      <td>2.112038</td>
      <td>8.480461</td>
      <td>1.213253</td>
      <td>1.740797</td>
      <td>12.746262</td>
    </tr>
    <tr>
      <td>71</td>
      <td>United States</td>
      <td>2000</td>
      <td>2.040500</td>
      <td>8.272097</td>
      <td>1.287739</td>
      <td>1.790995</td>
      <td>12.620268</td>
    </tr>
  </tbody>
</table>
<p>72 rows × 7 columns</p>
</div>



## Choose the Index Carefully

So, now that we know that we use index and column names for
aligning data, “how should we pick the index?” is a natural question to ask.

To guide us to the right answer, we will list the first two components
to [Hadley Wickham’s](http://hadley.nz/) description of [tidy
data](http://vita.had.co.nz/papers/tidy-data.html):

1. Each column should each have one variable.  
1. Each row should each have one observation.  


If we strive to have our data in a tidy form (we should), then when
choosing the index, we should set:

- the row labels (index) to be a unique identifier for an observation
  of data  
- the column names to identify one variable  


For example, suppose we are looking data on interest rates.

Each column might represent one bond or asset and each row might
represent the date.

Using hierarchical row and column indices allows us to store higher
dimensional data in our (inherently) two dimensional DataFrame.

### Know Your Goal

The correct column(s) to choose for the index often depends on the context of
your analysis.

For example, if I were studying how GDP and consumption evolved over time for
various countries, I would want time (year) and country name on the index

On the other hand, if I were trying to look at the differences across countries
and variables within a particular year, I may opt to put the country and
variable on the index and have years be columns.

Following the tidy data rules above and thinking about how you intend to *use*
the data – and a little practice – will enable you to consistently select the
correct index.

ipynb
ebcf492e7698a99f3ce9f794e690ae1140e654f3
Jupyter Notebook
71497927ed4d54ddf6fd5abe2ddabb5966eb0304
Apache-2.0
remi-sudo/Classes
Session_7/3_the_index.ipynb
71497927ed4d54ddf6fd5abe2ddabb5966eb0304
Apache-2.0
remi-sudo/Classes
Session_7/3_the_index.ipynb
71497927ed4d54ddf6fd5abe2ddabb5966eb0304
Apache-2.0
remi-sudo/Classes
Session_7/3_the_index.ipynb