PandasでMultiindex

参考URL : [https://jakevdp.github.io/PythonDataScienceHandbook/03.05-hierarchical-indexing.html](https://jakevdp.github.io/PythonDataScienceHandbook/03.05-hierarchical-indexing.html)

データフレーム作成

```
# hierarchical indices and columns
index = pd.MultiIndex.from_product([[2013, 2014], [1, 2]],
                                   names=['year', 'visit'])
columns = pd.MultiIndex.from_product([['Bob', 'Guido', 'Sue'], ['HR', 'Temp']],
                                     names=['subject', 'type'])

# mock some data
data = np.round(np.random.randn(4, 6), 1)
data[:, ::2] *= 10
data += 37

# create the DataFrame
health_data = pd.DataFrame(data, index=index, columns=columns)
health_data
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278468/3053ef13-1e42-9ba7-3dc8-f8f8330bd15f.png)


列のHRのみにアクセス。idxを使わない方法もあるけど、使う方法を覚えといた方が良いかもしれない。

```
idx = pd.IndexSlice
health_data.loc[idx[:,:],idx[:,'HR']]
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278468/950cd727-29ad-93bc-f3c5-f2e1fee34c1b.png)



行のvisit=1のみにアクセス

```
idx = pd.IndexSlice
health_data.loc[idx[:,1],idx[:,:]]
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278468/959e7687-0b1f-ffd3-a2cb-861974a4776d.png)


Guido列とSue列にアクセス

```
health_data[['Guido','Sue']]
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278468/c09526a5-c5c1-46fb-9416-d0714961f577.png)



BobのHRにアクセス

```
health_data.loc[:,('Bob','HR')]
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278468/ec359cac-b37d-b72b-8835-3023497cc499.png)



既存のデータフレームにindexを追加する場合は、以下のように再定義する。

```
idx = pd.MultiIndex.from_arrays([df['group'],df['name']])
df.index = idx
```

index名にアクセス

```
> health_data.index.get_level_values(1)
Int64Index([1, 2, 1, 2], dtype='int64', name='visit')
```

条件を指定して抽出。※`~health_data.index.get_level_values(1).isin(リスト)`でも良い。これは複数条件指定出来る。

```
idx = health_data.index.get_level_values(1)!=1
health_data.loc[idx,]
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278468/40a78b1e-246c-89d2-6c5f-4b271daf6c14.png)

# 条件抽出 複数指定

条件を複数指定出来る。HR列を抽出


```python
idx = pd.IndexSlice
cnd = health_data.columns.get_level_values(1).isin(['HR'])
health_data.loc[idx[:,:],idx[:,cnd]]
```




<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;
    }

    .dataframe thead tr:last-of-type th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr>
      <th></th>
      <th>subject</th>
      <th>Bob</th>
      <th>Guido</th>
      <th>Sue</th>
    </tr>
    <tr>
      <th></th>
      <th>type</th>
      <th>HR</th>
      <th>HR</th>
      <th>HR</th>
    </tr>
    <tr>
      <th>year</th>
      <th>visit</th>
      <th></th>
      <th></th>
      <th></th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th rowspan="2" valign="top">2013</th>
      <th>1</th>
      <td>37.0</td>
      <td>30.0</td>
      <td>26.0</td>
    </tr>
    <tr>
      <th>2</th>
      <td>38.0</td>
      <td>39.0</td>
      <td>43.0</td>
    </tr>
    <tr>
      <th rowspan="2" valign="top">2014</th>
      <th>1</th>
      <td>26.0</td>
      <td>33.0</td>
      <td>22.0</td>
    </tr>
    <tr>
      <th>2</th>
      <td>34.0</td>
      <td>39.0</td>
      <td>26.0</td>
    </tr>
  </tbody>
</table>
</div>



HR列「以外」を抽出


```python
idx = pd.IndexSlice
cnd = ~health_data.columns.get_level_values(1).isin(['HR'])
health_data.loc[idx[:,:],idx[:,cnd]]
```




<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;
    }

    .dataframe thead tr:last-of-type th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr>
      <th></th>
      <th>subject</th>
      <th>Bob</th>
      <th>Guido</th>
      <th>Sue</th>
    </tr>
    <tr>
      <th></th>
      <th>type</th>
      <th>Temp</th>
      <th>Temp</th>
      <th>Temp</th>
    </tr>
    <tr>
      <th>year</th>
      <th>visit</th>
      <th></th>
      <th></th>
      <th></th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th rowspan="2" valign="top">2013</th>
      <th>1</th>
      <td>35.9</td>
      <td>36.2</td>
      <td>37.8</td>
    </tr>
    <tr>
      <th>2</th>
      <td>37.0</td>
      <td>37.1</td>
      <td>38.5</td>
    </tr>
    <tr>
      <th rowspan="2" valign="top">2014</th>
      <th>1</th>
      <td>38.5</td>
      <td>37.3</td>
      <td>36.8</td>
    </tr>
    <tr>
      <th>2</th>
      <td>37.1</td>
      <td>37.2</td>
      <td>37.1</td>
    </tr>
  </tbody>
</table>
</div>