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.308249print 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)。詳しくはマニュアル参照。