pandas

Pandasでdataframeを合併する

More than 1 year has passed since last update.

複数の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]
})

Screen Shot 2017-08-04 at 8.43.34.png Screen Shot 2017-08-04 at 8.44.16.png

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

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

Screen Shot 2017-08-04 at 8.37.48.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]
})

Screen Shot 2017-08-04 at 8.45.10.png Screen Shot 2017-08-04 at 8.44.16.png

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

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

Screen Shot 2017-08-04 at 8.46.58.png

how='outer'を指定すると, 温度の4レコード全部反映された.

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

Screen Shot 2017-08-04 at 8.50.15.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]
})

Screen Shot 2017-08-04 at 8.56.06.png Screen Shot 2017-08-04 at 8.57.13.png

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

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

Screen Shot 2017-08-04 at 8.59.30.png

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

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

Screen Shot 2017-08-04 at 9.02.22.png

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

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

Screen Shot 2017-08-04 at 9.06.17.png

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

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

Screen Shot 2017-08-04 at 9.08.28.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]
})

Screen Shot 2017-08-04 at 11.28.27.png Screen Shot 2017-08-04 at 11.29.05.png

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

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

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

Screen Shot 2017-08-04 at 11.32.54.png Screen Shot 2017-08-04 at 11.32.44.png

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

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

Screen Shot 2017-08-04 at 11.34.35.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]
})

Screen Shot 2017-08-04 at 12.01.00.png Screen Shot 2017-08-04 at 12.01.22.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]
})

Screen Shot 2017-08-04 at 12.08.52.png Screen Shot 2017-08-04 at 12.09.03.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('時刻')

Screen Shot 2017-08-05 at 7.57.08.png Screen Shot 2017-08-05 at 7.57.33.png

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

Screen Shot 2017-08-05 at 7.58.29.png

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

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

Screen Shot 2017-08-05 at 8.02.02.png