Pandasでdataframeを合併する

複数のCSVファイルから読み込んたデータを合併するのよくやっているため，Pythonのpandasライブラリでデータを合併するやり方を簡単にまとめます．


### 例1
時間軸で2つのdataframeを連結(時刻と言ってもただの文字列str）

```
import pandas as pd

# 温度データ
df_temp = pd.DataFrame({
            '時刻': ['2017-08-01 01:00:00', '2017-08-01 02:00:00', '2017-08-01 03:00:00'], 
            '温度': [21, 22, 23]
})

# 湿度データ
df_humi = pd.DataFrame({
            '時刻': ['2017-08-01 01:00:00', '2017-08-01 02:00:00', '2017-08-01 03:00:00'], 
            '湿度': [41, 42, 43]
})
```
<img width="203" alt="Screen Shot 2017-08-04 at 8.43.34.png" src="https://qiita-image-store.s3.amazonaws.com/0/54698/1fa1bbeb-b8c8-5967-55dc-7d82adaf9c03.png"> <img width="199" alt="Screen Shot 2017-08-04 at 8.44.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/54698/97011c76-31af-f78f-036d-091ac28ea367.png">


時刻は一致しているので，きれいにmergeしてくれている．

```
result = pd.merge(df_temp, df_humi, on='時刻')
```

<img width="239" alt="Screen Shot 2017-08-04 at 8.37.48.png" src="https://qiita-image-store.s3.amazonaws.com/0/54698/2da87c07-061b-a854-6d06-cc0c90eddcf1.png">



### 例2

レコード数一致していないときに

```
import pandas as pd

# 温度データ
df_temp = pd.DataFrame({
            '時刻': ['2017-08-01 01:00:00', '2017-08-01 02:00:00', '2017-08-01 03:00:00', '2017-08-01 04:00:00'], 
            '温度': [21, 22, 23, 24]
})

# 湿度データ
df_humi = pd.DataFrame({
            '時刻': ['2017-08-01 01:00:00', '2017-08-01 02:00:00', '2017-08-01 03:00:00'], 
            '湿度': [41, 42, 43]
})
```

<img width="197" alt="Screen Shot 2017-08-04 at 8.45.10.png" src="https://qiita-image-store.s3.amazonaws.com/0/54698/b6bb8078-e19a-9663-0bd9-b87ed4db121f.png"> <img width="199" alt="Screen Shot 2017-08-04 at 8.44.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/54698/97011c76-31af-f78f-036d-091ac28ea367.png">

このままmergeすると自動的に`inner join`のように温度データ最後のレコード反映されない．

```
result = pd.merge(df_temp, df_humi, on='時刻')
```

<img width="237" alt="Screen Shot 2017-08-04 at 8.46.58.png" src="https://qiita-image-store.s3.amazonaws.com/0/54698/d8a0c8d4-bdd0-138a-ae13-79165cd270e7.png">

`how='outer'`を指定すると， 温度の４レコード全部反映された．
```
result = pd.merge(df_temp, df_humi, on='時刻', how='outer')
```

<img width="230" alt="Screen Shot 2017-08-04 at 8.50.15.png" src="https://qiita-image-store.s3.amazonaws.com/0/54698/cf816aca-1c90-13a5-3698-14072cb50c81.png">


### 例3

時刻が一致していない

```
import pandas as pd

# 温度データ 2017-08-01 04:00:00が追加されている

df_temp = pd.DataFrame({
            '時刻': ['2017-08-01 01:00:00', '2017-08-01 02:00:00', '2017-08-01 03:00:00', '2017-08-01 04:00:00'], 
            '温度': [21, 22, 23, 24]
})

# 湿度データ 2017-08-01 05:00:00が追加されている

df_humi = pd.DataFrame({
            '時刻': ['2017-08-01 01:00:00', '2017-08-01 02:00:00', '2017-08-01 03:00:00', '2017-08-01 05:00:00'], 
            '湿度': [41, 42, 43, 45]
})
```

<img width="198" alt="Screen Shot 2017-08-04 at 8.56.06.png" src="https://qiita-image-store.s3.amazonaws.com/0/54698/0d0d01f0-b9a6-98af-94e7-0398e6e18d7f.png"> <img width="201" alt="Screen Shot 2017-08-04 at 8.57.13.png" src="https://qiita-image-store.s3.amazonaws.com/0/54698/f3844da5-c913-509c-d23e-beb792189109.png">

共通の時刻だけでdataframeをmergeしている．

```
result = pd.merge(df_temp, df_humi, on='時刻')
```

<img width="240" alt="Screen Shot 2017-08-04 at 8.59.30.png" src="https://qiita-image-store.s3.amazonaws.com/0/54698/992ff88c-97fc-cf61-6dca-8c746f0b6490.png">


`how='outer'`を指定して両方を時刻が含まれるようになった

```
result = pd.merge(df_temp, df_humi, on='時刻', how='outer')
```

<img width="239" alt="Screen Shot 2017-08-04 at 9.02.22.png" src="https://qiita-image-store.s3.amazonaws.com/0/54698/a23d34b0-3127-eb92-79f5-a58aab7949c0.png">


`how='left'`を指定すると，左の`df_temp`温度データの時刻に合わせて，mergeしてくれている

```
result = pd.merge(df_temp, df_humi, on='時刻', how='left')
```
<img width="237" alt="Screen Shot 2017-08-04 at 9.06.17.png" src="https://qiita-image-store.s3.amazonaws.com/0/54698/1c0f34f8-9bac-305b-898e-61c28d6de716.png">


`how='right'`を指定すると，右の`df_humi`湿度データの時刻に合わせて，mergeしてくれている

```
result = pd.merge(df_temp, df_humi, on='時刻', how='right')
```
<img width="230" alt="Screen Shot 2017-08-04 at 9.08.28.png" src="https://qiita-image-store.s3.amazonaws.com/0/54698/efa1da03-aa8c-2590-0a91-2e6f8c7e9fc0.png">

### 例4

時刻のフォーマットが一致していない時

```
import pandas as pd
df_temp = pd.DataFrame({
            '時刻': ['2017-08-01 01:00:00', '2017-08-01 02:00:00',  '2017-08-01 03:10:00'], 
            '温度': [21, 22, 23]
})


df_humi = pd.DataFrame({
            '時刻': ['2017-08-01 1:00', '2017-08-01 2:00', '2017-08-01 3:00'], 
            '湿度': [41, 42, 43]
})
```


<img width="203" alt="Screen Shot 2017-08-04 at 11.28.27.png" src="https://qiita-image-store.s3.amazonaws.com/0/54698/eea484be-4dfa-9fda-976e-d53b195aed39.png"> <img width="183" alt="Screen Shot 2017-08-04 at 11.29.05.png" src="https://qiita-image-store.s3.amazonaws.com/0/54698/5384b26a-da77-bb55-b9be-fc8bb7657afc.png">

まず時刻のフォーマットを`pandas.to_datetime()`関数で揃える

```
df_temp['時刻'] = pd.to_datetime(df_temp['時刻'])

df_humi['時刻'] = pd.to_datetime(df_humi['時刻'])
```

<img width="201" alt="Screen Shot 2017-08-04 at 11.32.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/54698/94500e6e-b48f-e646-7a4c-bfb54588550f.png"> <img width="200" alt="Screen Shot 2017-08-04 at 11.32.44.png" src="https://qiita-image-store.s3.amazonaws.com/0/54698/c89db626-c6bc-141e-6b8b-5d54a64bcdde.png">

湿度データの時刻に合わせて，mergeする

```
result = pd.merge(df_temp, df_humi, on='時刻', how='right')
```

<img width="238" alt="Screen Shot 2017-08-04 at 11.34.35.png" src="https://qiita-image-store.s3.amazonaws.com/0/54698/81765d0d-5319-d5d2-6d48-18dc638a10b2.png">


### 例5
データをmergeする前に`温度データの時刻` すべて `湿度データの時刻`に含まれているかを知りたいので，チェックする

```
# 温度データ
df_temp = pd.DataFrame({
            '時刻': ['2017-08-01 01:00:00', '2017-08-01 02:00:00', '2017-08-01 03:00:00'], 
            '温度': [21, 22, 23]
})

# 湿度データ
df_humi = pd.DataFrame({
            '時刻': ['2017-08-01 01:00:00', '2017-08-01 02:00:00', '2017-08-01 03:00:00', '2017-08-01 04:00:00' ], 
            '湿度': [41, 42, 43, 44]
})

```

<img width="200" alt="Screen Shot 2017-08-04 at 12.01.00.png" src="https://qiita-image-store.s3.amazonaws.com/0/54698/1e3e180d-0149-9656-e823-1a6a8d54b18d.png"> <img width="202" alt="Screen Shot 2017-08-04 at 12.01.22.png" src="https://qiita-image-store.s3.amazonaws.com/0/54698/88c33bf0-671a-811e-6756-3ebc0235940c.png">

```
set(df_temp['時刻']).issubset(df_humi['時刻'])
```
結果：True


温度データの時刻を少し修正する．

```
# 温度データ, 2017-08-01 03:00:00 -> 2017-08-01 03:10

df_temp = pd.DataFrame({
            '時刻': pd.to_datetime(['2017-08-01 01:00:00', '2017-08-01 02:00:00', '2017-08-01 03:10']),
            '温度': [21, 22, 23]
})

# 湿度データ
df_humi = pd.DataFrame({
            '時刻': pd.to_datetime(['2017-08-01 01:00:00', '2017-08-01 02:00:00', '2017-08-01 03:00:00', '2017-08-01 04:00:00' ]),
            '湿度': [41, 42, 43, 44]
})

```

<img width="198" alt="Screen Shot 2017-08-04 at 12.08.52.png" src="https://qiita-image-store.s3.amazonaws.com/0/54698/2767be34-2e22-f001-8cf4-bfed895fac3f.png"> <img width="199" alt="Screen Shot 2017-08-04 at 12.09.03.png" src="https://qiita-image-store.s3.amazonaws.com/0/54698/dcd9e70f-c194-d90c-eb87-c1a3a6e39c55.png"> 


```
set(df_temp['時刻']).issubset(df_humi['時刻'])
```
結果： False


### 例6
indexを合わせて，mergeする

```
# 温度データ
df_temp = pd.DataFrame({
            '時刻': ['2017-08-01 01:00:00', '2017-08-01 02:00:00', '2017-08-01 03:00:00'], 
            '温度': [21, 22, 23]
})

# 湿度データ
df_humi = pd.DataFrame({
            '時刻': ['2017-08-01 01:00:00', '2017-08-01 02:00:00'], 
            '湿度': [41, 42]
})

df_temp= df_temp.set_index('時刻')
df_humi = df_humi.set_index('時刻')
```
<img width="176" alt="Screen Shot 2017-08-05 at 7.57.08.png" src="https://qiita-image-store.s3.amazonaws.com/0/54698/7ad261f9-ad9c-f417-af3e-53420c15daa9.png"> <img width="170" alt="Screen Shot 2017-08-05 at 7.57.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/54698/7239d7ae-bf2d-c4f2-45a0-d9be40c5d56d.png"> 


```
merged = pd.merge(df_temp, df_humi, left_index=True,right_index=True)
merged
```

<img width="203" alt="Screen Shot 2017-08-05 at 7.58.29.png" src="https://qiita-image-store.s3.amazonaws.com/0/54698/f1706b7a-0891-5d34-161c-9d8cc592093e.png">


`how='left'`を指定して左の温度データのindexに合わせてmergeする．

```
merged = pd.merge(df_temp, df_humi, left_index=True,right_index=True, how='left')
merged
```

<img width="203" alt="Screen Shot 2017-08-05 at 8.02.02.png" src="https://qiita-image-store.s3.amazonaws.com/0/54698/1dc753b8-f00e-5e80-7916-fd2c612180d6.png">