pandasによるpivot 〜 複数行に渡って重複しているデータを、重複しているデータ毎に集計する

pandas.DataFrameの結合」の続き。

例によってAAPLとMSFTの株価データを題材に色々試す。

1.株価データ取得
途中、pandas.DataFrame.insertを使用して列を追加していることに注意。

#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)

# 株価データ取得
aapl = pdd.DataReader('AAPL', "yahoo", date_from, date_to)
msft = pdd.DataReader('MSFT', "yahoo", date_from, date_to)

# 「Symbol」という名前の列を追加
aapl.insert(0, 'Symbol', 'AAPL')
msft.insert(0, 'Symbol', 'MSFT')

print ""
print "print aapl"
print aapl

print ""
print "print msft"
print msft

結果は次。

print aapl
Symbol Open High Low Close Volume \
Date
2016-09-26 AAPL 111.639999 113.389999 111.550003 112.879997 29869400
2016-09-27 AAPL 113.000000 113.180000 112.339996 113.089996 24607400
2016-09-28 AAPL 113.690002 114.639999 113.430000 113.949997 29641100
2016-09-29 AAPL 113.160004 113.800003 111.800003 112.180000 35887000
2016-09-30 AAPL 112.459999 113.370003 111.800003 113.050003 36379100
2016-10-03 AAPL 112.709999 113.050003 112.279999 112.519997 21701800
2016-10-04 AAPL 113.059998 114.309998 112.629997 113.000000 29736800
2016-10-05 AAPL 113.400002 113.660004 112.690002 113.050003 21453100
2016-10-06 AAPL 113.699997 114.339996 113.129997 113.889999 28779300

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 msft
Symbol Open High Low Close Volume \
Date
2016-09-26 MSFT 57.080002 57.139999 56.830002 56.900002 21688700
2016-09-27 MSFT 56.930000 58.060001 56.680000 57.950001 28065100
2016-09-28 MSFT 57.880001 58.060001 57.669998 58.029999 20536400
2016-09-29 MSFT 57.810001 58.169998 57.209999 57.400002 25463500
2016-09-30 MSFT 57.570000 57.770000 57.340000 57.599998 29910800
2016-10-03 MSFT 57.410000 57.549999 57.060001 57.419998 19189500
2016-10-04 MSFT 57.270000 57.599998 56.970001 57.240002 20085900
2016-10-05 MSFT 57.290001 57.959999 57.259998 57.639999 16726400
2016-10-06 MSFT 57.740002 57.860001 57.279999 57.740002 16212600

Adj Close
Date
2016-09-26 56.518189
2016-09-27 57.561143
2016-09-28 57.640604
2016-09-29 57.014834
2016-09-30 57.213489
2016-10-03 57.034697
2016-10-04 56.855908
2016-10-05 57.253222
2016-10-06 57.352553

2.マージしてpivot対象のテストデータを作成する
1で取得した2つの株価データを連結する。
連結する部分のコードだけを書くと次。

# 2つのデータフレームを結合
AAPL_MSFT = pd.concat([msft, aapl]).sort_index()

print AAPL_MSFT

結果は次のようになり、AAPLとMSFTのデータが複数行に渡って混ざっているデータとなる。

Symbol Open High Low Close Volume \
Date
2016-09-26 MSFT 57.080002 57.139999 56.830002 56.900002 21688700
2016-09-26 AAPL 111.639999 113.389999 111.550003 112.879997 29869400
2016-09-27 MSFT 56.930000 58.060001 56.680000 57.950001 28065100
2016-09-27 AAPL 113.000000 113.180000 112.339996 113.089996 24607400
2016-09-28 MSFT 57.880001 58.060001 57.669998 58.029999 20536400
2016-09-28 AAPL 113.690002 114.639999 113.430000 113.949997 29641100
2016-09-29 MSFT 57.810001 58.169998 57.209999 57.400002 25463500
2016-09-29 AAPL 113.160004 113.800003 111.800003 112.180000 35887000
2016-09-30 MSFT 57.570000 57.770000 57.340000 57.599998 29910800
2016-09-30 AAPL 112.459999 113.370003 111.800003 113.050003 36379100
2016-10-03 MSFT 57.410000 57.549999 57.060001 57.419998 19189500
2016-10-03 AAPL 112.709999 113.050003 112.279999 112.519997 21701800
2016-10-04 MSFT 57.270000 57.599998 56.970001 57.240002 20085900
2016-10-04 AAPL 113.059998 114.309998 112.629997 113.000000 29736800
2016-10-05 MSFT 57.290001 57.959999 57.259998 57.639999 16726400
2016-10-05 AAPL 113.400002 113.660004 112.690002 113.050003 21453100
2016-10-06 MSFT 57.740002 57.860001 57.279999 57.740002 16212600
2016-10-06 AAPL 113.699997 114.339996 113.129997 113.889999 28779300

Adj Close
Date
2016-09-26 56.518189
2016-09-26 112.303406
2016-09-27 57.561143
2016-09-27 112.512333
2016-09-28 57.640604
2016-09-28 113.367940
2016-09-29 57.014834
2016-09-29 111.606985
2016-09-30 57.213489
2016-09-30 112.472544
2016-10-03 57.034697
2016-10-03 111.945245
2016-10-04 56.855908
2016-10-04 112.422796
2016-10-05 57.253222
2016-10-05 112.472544
2016-10-06 57.352553
2016-10-06 113.308249

3.複数行に渡って重複しているデータをpivotingする
例えば、カラム「Symbol」のデータには、「AAPL」と「MSFT」という2つのデータが重複している。
これを、「AAPL」と「MSFT」毎に集計する。
集計対象のデータは、「Open」、「High」、「Low」、「Close」、「Volume」、「Adj Close」があるが、ここでは「Adj Close」を集計する。
※)pivotするデータの前提として、カラムとするデータと行とするデータのペアが一意でなければならない
例えば、Dateとカラム「Symbol」のペアは一意だが、カラム「Symbol」とカラム「Symbol」のペアは当然重複するのでエラー
※)また、pivotするデータはカラムデータなので、インデックスとなっている「Date」はカラムデータにしておく必要がある。

以上の前提を踏まえてpivotすると次のようになる。

#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)

# 株価データ取得
aapl = pdd.DataReader('AAPL', "yahoo", date_from, date_to)
msft = pdd.DataReader('MSFT', "yahoo", date_from, date_to)

# 「Symbol」という名前の列を追加
aapl.insert(0, 'Symbol', 'AAPL')
msft.insert(0, 'Symbol', 'MSFT')

# 2つのデータフレームを結合
AAPL_MSFT = pd.concat([msft, aapl]).sort_index()

# indexをresetしてDateをカラムデータと認識させる
AAPL_MSFT = AAPL_MSFT.reset_index()

# pivot集計する
adjClose = AAPL_MSFT.pivot(
    index='Date',
    columns='Symbol',
    values='Adj Close'
)

print ""
print "print adjClose"
print adjClose