pandas.DataFrameの結合

pandas.DataFrameの連結」の続き。

pandas.mergeとpandas.concatの違いは、pandas.mergeはインデックスのラベルを使用するのではなく共通のカラムデータを元に結合すること。

次のように動作する。

1.マージに使用するカラムデータが探される
2.1で探したカラムを元に、inner joinする
※)デフォルトでは、joinに使用されるカラムは2つのDataFrameにある同じ名前のカラムとなる。

具体的にみてみる。
まず、次のようにAAPLの調整後終値出来高のデータをDataFrame型で取得する。

#coding:utf-8
import numpy as np
import pandas as pd
import datetime
import pandas_datareader.data as pdd

# 期間設定
date_from = datetime.date(2016, 9, 24)

######## DataFrameのマージ ########
aapl = pdd.DataReader('AAPL', "yahoo", date_from, date_to)

aaplAdjClose_201609_Df  = aapl[['Adj Close']]
aaplVol_201609_Df       = aapl[['Volume']]

print ""
print "print aaplAdjClose_201609_Df"
print aaplAdjClose_201609_Df
print ""
print "print aaplVol_201609_Df"
print aaplVol_201609_Df

実行結果は次。

print aaplAdjClose_201609_Df
Adj Close
Date
2016-09-26 112.303406
2016-09-27 112.512333
2016-09-28 113.367940
2016-09-29 111.606985
2016-09-30 112.472544
2016-10-03 111.945245
2016-10-04 112.422796
2016-10-05 112.472544
2016-10-06 113.308249

print aaplVol_201609_Df
Volume
Date
2016-09-26 29869400
2016-09-27 24607400
2016-09-28 29641100
2016-09-29 35887000
2016-09-30 36379100
2016-10-03 21701800
2016-10-04 29736800
2016-10-05 21453100
2016-10-06 28779300

この2つをmergeするが、次のように実行すればエラーとなる。

mergedAAPL = pd.merge(
    aaplAdjClose_201609_Df,
    aaplVol_201609_Df
)

エラー内容は次。
共通のカラムが存在しないのでエラー。つまり、インデックスは共通しているが、カラムを元に結合するので共通のカラムが無いと駄目

in _validate_specification
raise MergeError('No common columns to perform merge on')
pandas.tools.merge.MergeError: No common columns to perform merge on

そのため、次のようにreset_index()を使用してインデックス(この場合Date)をインデックスから外してカラムとする。

aaplAdjClose_201609_Df_reset = aaplAdjClose_201609_Df.reset_index()
aaplVol_201609_Df_reset = aaplVol_201609_Df.reset_index()

これを考慮して次のように書き直す。

#coding:utf-8
import numpy as np
import pandas as pd
import datetime
import pandas_datareader.data as pdd

# 期間設定
date_from = datetime.date(2016, 9, 24)

######## DataFrameのマージ ########
aapl = pdd.DataReader('AAPL', "yahoo", date_from, date_to)

aaplAdjClose_201609_Df  = aapl[['Adj Close']]
aaplVol_201609_Df       = aapl[['Volume']]

# インデックスをリセット
aaplAdjClose_201609_Df_reset = aaplAdjClose_201609_Df.reset_index()
aaplVol_201609_Df_reset = aaplVol_201609_Df.reset_index()

# マージ実行
mergedAAPL = pd.merge(
    aaplAdjClose_201609_Df_reset,
    aaplVol_201609_Df_reset
)

print ""
print "print mergedAAPL"
print mergedAAPL

実行結果は次。2つのデータフレームに共通のカラム「Date」を元に結合されている。

print mergedAAPL
Date Adj Close Volume
0 2016-09-26 112.303406 29869400
1 2016-09-27 112.512333 24607400
2 2016-09-28 113.367940 29641100
3 2016-09-29 111.606985 35887000
4 2016-09-30 112.472544 36379100
5 2016-10-03 111.945245 21701800
6 2016-10-04 112.422796 29736800
7 2016-10-05 112.472544 21453100
8 2016-10-06 113.308249 28779300

共通のカラムのデータを元に結合するのだから、片側のデータが足りなかったら少ない方に合わせて結合されるはず。
試しにAAPLの株価を9月のものに絞り込んでから結合する。

#coding:utf-8
import numpy as np
import pandas as pd
import datetime
import pandas_datareader.data as pdd

# 期間設定
date_from = datetime.date(2016, 9, 24)

######## DataFrameのマージ ########
aapl = pdd.DataReader('AAPL', "yahoo", date_from, date_to)

aaplAdjClose_201609_Df  = aapl['2016-09'][['Adj Close']] #2016年9月に絞り込む
aaplVol_201609_Df       = aapl[['Volume']]

# インデックスをリセット
aaplAdjClose_201609_Df_reset = aaplAdjClose_201609_Df.reset_index()
aaplVol_201609_Df_reset = aaplVol_201609_Df.reset_index()

# マージ実行
mergedAAPL = pd.merge(
    aaplAdjClose_201609_Df_reset,
    aaplVol_201609_Df_reset
)

print ""
print "print mergedAAPL"
print mergedAAPL

案の定、9月のデータのみとなった。

print mergedAAPL
Date Adj Close Volume
0 2016-09-26 112.303406 29869400
1 2016-09-27 112.512333 24607400
2 2016-09-28 113.367940 29641100
3 2016-09-29 111.606985 35887000
4 2016-09-30 112.472544 36379100

さて、それでは結合する際のカラムはどのように指定するのか。それは「on」オプションで指定する。
詳しくはマニュアル参照
結合部分をオプション名を明示すると次のようになる。

mergedAAPL = pd.merge(
    left=aaplAdjClose_201609_Df_reset,
    right=aaplVol_201609_Df_reset,
    on='Date'
)

結合方法は「how」で指定できる(デフォルトはinner)。詳しくはマニュアル参照