Edited at

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]
})

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

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


例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]
})

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

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

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



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


例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]
})

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

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

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

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

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

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

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

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


例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]
})

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

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

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

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

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


例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]
})

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]
})

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('時刻')

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

merged

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

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

merged