pandas によるデータセットのマージ

## pandas の最新バージョン 0.14.0

[pandas](http://pandas.pydata.org/pandas-docs/stable/index.html) の最新版 0.14.0 が 5/30 にリリースされました。旧バージョンである 0.13.1 からアップグレードするには以下のコマンドを投入します。

```bash
pip install --upgrade pandas 
```

## データセットのマージ

[pandas](http://pandas.pydata.org/pandas-docs/stable/index.html) がデータフレームというオブジェクトを提供する高水準で強力な分析ライブラリであることは[以前にも紹介した](http://qiita.com/ynakayama/items/4362c439d9ea814cbe60)ばかりですが、これを利用して RDBMS のように複数のデータセットを結合することができます。

### 実際のデータセットから試す

pandas の read_json 関数は JSON をそのままデータフレームとして扱うことができます。ここではオープンソースプロジェクトである [House API Project](http://house-api-project.org/) の API を利用してみます。ここではセンサーを利用して Wifi クライアント接続数や温度といった情報がオープンデータとして公開されています。これをマージしてみましょう。

```py3
import pandas as pd

# 1F の Wifi の接続数を最新 100 件取得する
wifi = pd.read_json('http://house-api-project.org/api/shibuhouse/wifi/clients?limit=100house-api-project.org/api/shibuhouse/wifi/1f/clients?limit=100')

# 1F の温度を最新 100 件取得する
temp = pd.read_json('http://house-api-project.org/api/shibuhouse/1f/temperature?limit=100')

print( wifi.head(5) )
#=>
#                                       _id  clients                     time
#  0   {'$oid': '538c3799c3ca7c08531d645e'}       21  2014-06-02 08:36:36 UTC
#  1   {'$oid': '538c3760c3ca7c08531d6454'}       21  2014-06-02 08:35:37 UTC
#  2   {'$oid': '538c371fc3ca7c08531d6445'}       21  2014-06-02 08:34:36 UTC
#  3   {'$oid': '538c36e4c3ca7c08531d643b'}       21  2014-06-02 08:33:37 UTC
#  4   {'$oid': '538c36a7c3ca7c08531d642f'}       21  2014-06-02 08:32:36 UTC

print( temp.head(5) )
#=>
#                                       _id  temperature                     time
#  0   {'$oid': '538c37cac3ca7c08531d6465'}       34.000  2014-06-02 08:37:29 UTC
#  1   {'$oid': '538c378dc3ca7c08531d6459'}       34.000  2014-06-02 08:36:29 UTC
#  2   {'$oid': '538c3752c3ca7c08531d644d'}       34.000  2014-06-02 08:35:29 UTC
#  3   {'$oid': '538c3715c3ca7c08531d6442'}       34.000  2014-06-02 08:34:29 UTC
#  4   {'$oid': '538c36dbc3ca7c08531d6437'}       34.000  2014-06-02 08:33:30 UTC

# ふたつのデータセットをインデックスでマージする
merged = pd.merge(wifi, temp, left_index=True, right_index=True)
```

### マージのための様々なオプション

よく利用する引数は下表の通りです。

|引数|説明|
|:--|:--|
|left|左側にマージをする|
|right|右側にマージをする|
|how|どのようにジョインするか (inner, outer, left, right)|
|on|マージに使う列名、明示的に指定したいときに|
|left_on/right_on|結合キーとして用いる別名|
|left_index/right_index|インデックスでマージしたいときに|

## データセットの連結

concat 関数はデータセットの連結をします。マージと似ていてわかりづらいのですが、詳細はドキュメントを読むのが良いでしょう。

Merge, join, and concatenate
http://pandas.pydata.org/pandas-docs/stable/merging.html

先ほどの JSON API の例で言うとこうなります。

```py3
concat = pd.concat([wifi, temp], ignore_index=True, axis=1)

concat.head(10)
#=>
#                                        0   1                        2  \
#  0  {'$oid': '538c4081c3ca7c08531d6616'}  20  2014-06-02 09:14:37 UTC   
#  1  {'$oid': '538c4045c3ca7c08531d660a'}  20  2014-06-02 09:13:37 UTC   
#  2  {'$oid': '538c4005c3ca7c08531d65fb'}  20  2014-06-02 09:12:37 UTC   
#  3  {'$oid': '538c3fcac3ca7c08531d65ef'}  20  2014-06-02 09:11:37 UTC   
#  4  {'$oid': '538c3f8ec3ca7c08531d65e4'}  20  2014-06-02 09:10:36 UTC   
#  5  {'$oid': '538c3f51c3ca7c08531d65d8'}  20  2014-06-02 09:09:36 UTC   
#  6  {'$oid': '538c3f17c3ca7c08531d65cf'}  20  2014-06-02 09:08:36 UTC   
#  7  {'$oid': '538c3edbc3ca7c08531d65c2'}  20  2014-06-02 09:07:37 UTC   
#  8  {'$oid': '538c3ea1c3ca7c08531d65b9'}  20  2014-06-02 09:06:36 UTC   
#  9  {'$oid': '538c3e61c3ca7c08531d65a8'}  22  2014-06-02 09:05:37 UTC   

#                                        3       4                        5  
#  0  {'$oid': '538c4077c3ca7c08531d6611'}  34.125  2014-06-02 09:14:30 UTC  
#  1  {'$oid': '538c403ac3ca7c08531d6606'}  34.125  2014-06-02 09:13:30 UTC  
#  2  {'$oid': '538c3fffc3ca7c08531d65fa'}  34.125  2014-06-02 09:12:30 UTC  
#  3  {'$oid': '538c3fc4c3ca7c08531d65ee'}  34.125  2014-06-02 09:11:31 UTC  
#  4  {'$oid': '538c3f86c3ca7c08531d65e2'}  34.125  2014-06-02 09:10:29 UTC  
#  5  {'$oid': '538c3f49c3ca7c08531d65d7'}  34.125  2014-06-02 09:09:29 UTC  
#  6  {'$oid': '538c3f0ec3ca7c08531d65cb'}  34.125  2014-06-02 09:08:29 UTC  
#  7  {'$oid': '538c3ed1c3ca7c08531d65bf'}  34.125  2014-06-02 09:07:29 UTC  
#  8  {'$oid': '538c3e96c3ca7c08531d65b3'}  34.125  2014-06-02 09:06:29 UTC  
#  9  {'$oid': '538c3e5bc3ca7c08531d65a7'}  34.125  2014-06-02 09:05:30 UTC  
```

### 連結のための様々なオプション

よく利用する引数は下表の通りです。

|引数|説明|
|:--|:--|
|objs|連結する pandas オブジェクトをリスト等で指定|
|axis|行か列か|
|join|inner か outer か、既定は outer|
|keys|連結するデータセット同士で関連付ける値|
|ignore_index|連結する軸とは別に新たなインデックスを生成する|

## まとめ

pandas を利用すると外部のデータセットを容易にマージしたり連結できることがわかりました。たとえばここからプロッティングすることで散布図を描いたり、相関関係を調べたりと色々な分析の可能性が見えてきますね。