note.nkmk.me

pandas-datareaderで株価や人口のデータを取得

Date: 2016-05-04 / tags: Python, pandas, スクレイピング

概要

pandas-datareaderを使うと、Web上の様々なソースに簡単にアクセスし、pandasDataFrameの形でデータを取得できる。

以前はpandas.ioという名前でpandasの一部として提供されていたが、今はpandas-datareaderとして独立している。

インストール

pipでインストールできる。

$ pip install pandas-datareader

データソース

以下のソースがサポートされている。

  • Yahoo! Finance
  • Google Finance
  • FRED
  • Fama/French
  • World Bank
  • OECD
  • Eurostat
  • EDGAR Index

株価(Yahoo! Finance)

Yahoo! Financeからソニー(SNE)の株価情報を取得してみる。なお、米Yahooからのデータなので、ニューヨーク証券取引所(NYSE)での株価で単位はドルとなる。

import pandas_datareader.data as web
import datetime

start = datetime.datetime(2010, 1, 1)
end = datetime.datetime(2015, 12, 31)
f = web.DataReader('SNE', 'yahoo', start, end)
print(f)
#                  Open       High        Low      Close  Adj Close   Volume
# Date                                                                      
# 2010-01-04  29.520000  30.180000  29.500000  30.020000  30.020000   988800
# 2010-01-05  29.719999  29.930000  29.500000  29.879999  29.879999   567800
# 2010-01-06  29.879999  29.950001  29.660000  29.850000  29.850000   468200
# 2010-01-07  29.740000  29.870001  29.590000  29.799999  29.799999   645300
# 2010-01-08  30.040001  30.469999  29.930000  30.410000  30.410000   574100
# ...               ...        ...        ...        ...        ...      ...
# 2015-12-24  24.580000  24.780001  24.570000  24.700001  24.700001   467400
# 2015-12-28  24.709999  24.790001  24.530001  24.670000  24.670000   590100
# 2015-12-29  24.860001  24.900000  24.680000  24.830000  24.830000   657600
# 2015-12-30  24.780001  24.900000  24.700001  24.719999  24.719999   344900
# 2015-12-31  24.670000  24.770000  24.510000  24.610001  24.610001   688900
# [1511 rows x 6 columns]

web.DataReader(name, data_source, start, end)の引数は以下のとおり。

  • name : データセットの名前。ティッカーシンボルを指定。strまたはlist
    • GOOG, AAPL, MSFTなど。
    • 日経平均(^N225)やダウ平均(^DJI)も。
  • data_source : データソースの名前。
    • Google Financeからデータを取得したい場合は'google'とする。
  • start : 取得したい期間の開始日時、datetime型で指定。
  • end : 取得したい期間の終了日時、datetime型で指定。

Yahoo! Financeの場合、取得できるデータは6項目。

複数のデータを同時に取得

ティッカーシンボルを指定するnameはリストも可能。ソニーとアップルの値を同時に取得してみる。

f = web.DataReader(['SNE', 'AAPL'], 'yahoo', start, end)
print(f['Adj Close'])
#                   AAPL        SNE
# Date                             
# 2015-12-31  101.703697  24.610001
# 2015-12-30  103.694107  24.719999
# 2015-12-29  105.066116  24.830000
# 2015-12-28  103.210999  24.670000
# 2015-12-24  104.380112  24.700001
# ...                ...        ...
# 2010-01-08   27.244156  30.410000
# 2010-01-07   27.064222  29.799999
# 2010-01-06   27.114347  29.850000
# 2010-01-05   27.552608  29.879999
# 2010-01-04   27.505054  30.020000
# [1511 rows x 2 columns]

なお、nameをリストにすると、取得できるのはpandas.DataFrameではなく、三次元構造のpandas.Panel。ここでは'Adj Close'の値を表示させている。

print(f)
# <class 'pandas.core.panel.Panel'>
# Dimensions: 6 (items) x 1511 (major_axis) x 2 (minor_axis)
# Items axis: Adj Close to Volume
# Major_axis axis: 2015-12-31 00:00:00 to 2009-12-31 00:00:00
# Minor_axis axis: AAPL to SNE

プロット

プロットするのも簡単。比較のため最初の値で規格化している。

import matplotlib.pyplot as plt

f['Adj Close']['SNE'] /= f['Adj Close']['SNE'][-1]
f['Adj Close']['AAPL'] /= f['Adj Close']['AAPL'][-1]
f['Adj Close'].plot(title='SNE vs AAPL', grid=True)
# plt.show()
plt.savefig('data/dst/pandas_datareader_yahoo.png')
pandas datareader 株価

人口、GDPなど(World Bank)

世界銀行が公開している人口、GDP、出生率などのマクロデータにアクセスできる。

日本とアメリカの人口を取得してみる。

from pandas_datareader import wb

f = wb.download(indicator='SP.POP.TOTL', country=['JP', 'US'],
                start=1960, end=2014)
print(f)
#                     SP.POP.TOTL
# country       year             
# Japan         2014    127276000
#               2013    127445000
#               2012    127629000
#               2011    127833000
#               2010    128070000
# ...                         ...
# United States 1989    246819000
#               1988    244499000
#               1987    242289000
# ...                         ...
#               1962    186538000
#               1961    183691000
#               1960    180671000
# [110 rows x 1 columns]

wb.download(indicator, country, start, end)の引数は以下のとおり。

  • indicator : データのID。後述。
  • country : 国名。strまたはlist
  • ISO 3166-1で定められた、2文字または3文字の国名コード。
  • start : 取得したい期間の開始年。int
  • end : 取得したい期間の終了年。int

indicator

indicatorで指定するIDは世界銀行のサイトで検索するか、wb.search()を使う。はじめのうちは世界銀行のサイトで検索するほうが取っ付きやすいと思う。

世界銀行のサイトで検索

世界銀行のサイトで検索する場合、

で検索できる。検索窓から飛んだ先の個別ページURLの末尾がIDとなる。

例えば、CO2排出量の場合、検索窓に「CO2」と入力するといくつか候補が挙げられるので、「CO2 emissions (kt)」を選んで「Go」をクリックすると、個別ページが表示される。IDは個別ページのURL(http://data.worldbank.org/indicator/EN.ATM.CO2E.KT)の末尾、'EN.ATM.CO2E.KT'となる。

主要な指標は「Indicators | Data」の下の方に列挙されているので、そこから選んでもよい。

wb.search()

wb.search()を使うとPython上でIDを検索できる。

例えば、per capita(一人あたり)、constant dollarsのGDPのIDを知りたい場合、引数に正規表現の文字列'gdp.*capita.*const'を入れる。

idと名前(簡単な説明)が表示されるので、所望のIDを選ぶ。

print(wb.search('gdp.*capita.*const').iloc[:, :2])
#                         id                                               name
# 685     6.0.GDPpc_constant  GDP per capita, PPP (constant 2011 internation...
# 8086        NY.GDP.PCAP.KD                 GDP per capita (constant 2010 US$)
# 8088        NY.GDP.PCAP.KN                      GDP per capita (constant LCU)
# 8090     NY.GDP.PCAP.PP.KD  GDP per capita, PPP (constant 2011 internation...
# 8091  NY.GDP.PCAP.PP.KD.87  GDP per capita, PPP (constant 1987 internation...

慣れないうちはちょっと難しい。

階層型インデックスの取り扱い

上の例で挙げたように、wb.download()で取得できるデータは階層型のインデックスとなっている。

#                     SP.POP.TOTL
# country       year             
# Japan         2014    127276000
#               2013    127445000
#               2012    127629000
#               2011    127833000
#               2010    128070000
# ...                         ...
# United States 1989    246819000
#               1988    244499000
#               1987    242289000
# ...                         ...
#               1962    186538000
#               1961    183691000
#               1960    180671000
# [110 rows x 1 columns]

グラフにプロットしたい場合などはこのままだと使いにくいので、unstack()を使い行から列へピボットする。

f = wb.download(indicator='SP.POP.TOTL', country=['JP', 'US'],
                start=1960, end=2014)
f2 = f.unstack(level=0)
print(f2)
#         SP.POP.TOTL              
# country       Japan United States
# year                             
# 1960       92500572     180671000
# 1961       94943000     183691000
# 1962       95832000     186538000
# 1963       96812000     189242000
# 1964       97826000     191889000
# ...                           ...
# 2010      128070000     309348193
# 2011      127833000     311663358
# 2012      127629000     313998379
# 2013      127445000     316204908
# 2014      127276000     318563456

'SP.POP.TOTL'が邪魔なので、columnsをリネームしてプロットする。

f2.columns = ['Japan', 'United States']
f2.plot(grid=True)
# plt.show()
plt.savefig('data/dst/pandas_datareader_wb.png')
pandas datareader 人口
スポンサーリンク
シェア

関連カテゴリー

関連記事