GIS奮闘記

元GISエンジニアの技術紹介ブログ。主にPythonを使用。

スポンサーリンク

PythonとJSMで東証一部上場企業を可視化してみる

ものすごく久しぶりのブログ更新になります。さぼり気味で元々しょぼい腕前がさらに錆びついた気が・・・今後はまた定期的に更新しようと思いますので、どうぞよろしくお願いします。さて、今回は「PythonとJSMで東証一部上場企業を可視化してみる」です。たくさんの企業が東証一部に上場していることはご存知かと思いますが、どの地域に一部上場企業が集まっているかはあまり意識したことがないのではないでしょうか?今回は上場企業の本社所在地に対してポイントをプロットしてみようと思います。とはいってもやっぱりほとんど東京のような気もしますが。。。

データ

データは一体どこからとってくるの?ってことになると思いますが、Yahoo!ファイナンスからとってくることができます。「jsm」というライブラリを使えば簡単に取得できます。作っていただいた方に感謝ですね。使用方法などはPyPIに記述されているので、そちらをご覧になってください。jsm 0.19 : Python Package Index

インストール

jsm, Pandas、geocoderのインストールをお願いします。また、今回はPandasを使用してスクレイピングをしますので、lxml、html5lib、BeautifulSoup4も必要です。インストールをお願いします。

環境

Windows7 64bit
ArcGIS10.2.0
Python2.7.3

事前準備

1.Company.gdbを作成します。
2.前回作成した日本地図を「Company.gdb」にコピーします(フィーチャクラス名は「Japan」)。
3.CompanyInfoフィーチャークラスを作成します。カラムは以下のように作成します。

f:id:sanvarie:20170108153149p:plain

f:id:sanvarie:20170108153155p:plain

f:id:sanvarie:20170108182218p:plain

このような感じになるかと思います。
f:id:sanvarie:20170108160203p:plain

株式市場の種類について

参考までに

日本の株式市場は、4つの証券取引所で成っています。今回は東証一部に限定しましたが、株式市場に上場している企業すべてを分析してみても面白そうですね。

東京証券取引所
1部・2部・マザーズ・ジャスダック・上場投信信託(ETF)・不動産投資信託J-REIT

名古屋証券取引所
1部・2部・セントレックス

札幌証券取引所
上場株式市場・アンビシャス

福岡証券取引所
上場株式市場・不動産投資信託J-REIT)・Q-Board

サンプルコード

東証一部上場企業の本社所在地にポイントをプロットするサンプルコードです

# -*- coding: utf-8 -*-
import arcpy
import geocoder
import jsm
import pandas as pd

#定数
INDUSTRY_CODE = "INDUSTRY_CODE"
INDUSTRY_NAME = "INDUSTRY_NAME"
BRAND_CODE = "BRAND_CODE"
BRAND_MARKET = "BRAND_MARKET"
BRAND_NAME = "BRAND_NAME"
LOCATION = "LOCATION"

#対象のフィーチャクラス
infc = r"C:\ArcPySample\Company.gdb\CompanyInfo"
spatial_reference=arcpy.SpatialReference(4612)

arcpy.env.workspace = r"C:\ArcPySample\Company.gdb"

def get_coordinate(location_name):
    try:
        ret = geocoder.google(location_name) #地名から座標を取得する
    except KeyError, e:
        print "KeyError(%s)" % str(e)
        return

    return ret

def create_point(df_merge):

    i = 0
    with arcpy.da.InsertCursor(infc, ["OID@","SHAPE@",INDUSTRY_CODE,INDUSTRY_NAME,BRAND_CODE,BRAND_MARKET,BRAND_NAME,LOCATION]) as cursor:

        for _,row in df_merge.iterrows():

            if row.LOCATION:
                loc = get_coordinate(row.LOCATION) #ジオコーディング

                if loc.lat is not None:
                    oid = i+1
                    point = arcpy.Point()
                    point.X = loc.lng
                    point.Y = loc.lat
                    pointGeometry = arcpy.PointGeometry(point,spatial_reference)

                    cursor.insertRow((oid,pointGeometry,row.INDUSTRY_CODE,row.INDUSTRY_NAME,row.BRAND_CODE,row.BRAND_MARKET,row.BRAND_NAME,row.LOCATION))
                    i = i + 1

def get_finace_data():

    q = jsm.Quotes()
    b = jsm.Brand()
    IDS = b.IDS

    data_list = []

    for industry_code in IDS.keys():

        industry_name = IDS[industry_code]
        brand_data = q.get_brand(industry_code) #企業情報を取得

        for brand in brand_data:
            if brand.market == u"東証1部":
                data_list.append([industry_code,industry_name,brand.ccode,brand.market,brand.name])

    brand_data_table = pd.DataFrame(data_list) #データフレームに格納
    brand_data_table.columns = [INDUSTRY_CODE,INDUSTRY_NAME,BRAND_CODE,BRAND_MARKET,BRAND_NAME]

    get_location(brand_data_table) #本社所在地を取得

def get_location(brand_data_table):

    location_list = []
    market_code = ""

    for _ ,row in brand_data_table.iterrows():

        #東証一部に限定したのでこの分岐は不要だが一応残しておく
        #if row.brand_market.find(u"札") > -1:
        #    market_code = u"S"
        #elif row.brand_market.find(u"名") > -1:
        #    market_code = u"N"
        #elif row.brand_market.find(u"福岡") > -1:
        #    market_code = u"F"
        #else:
        #    market_code = u"T"

        url = "http://stocks.finance.yahoo.co.jp/stocks/profile/?code=%s.T" % row.BRAND_CODE
        print url
        fetched_dataframes = pd.io.html.read_html(url) # pandasで本社所在地をスクレイピング

        try:
            location_data = fetched_dataframes[1][1][2] # 本社所在地の要素を取得

            if location_data.find(u"[") > -1: # [周辺地図]もしくは[主要事業所]という文言が本社所在地に含まれてしまっている会社があるので
                location_data = location_data[:location_data.find("[")]

            if location_data.find(u"〒") > -1: #郵便番号ははずす
                location_data = location_data[10:]
        except Exception as e:
            print "error"
        else:
            location_list.append([row.BRAND_CODE,location_data])

    location_data_table = pd.DataFrame(location_list) #データフレームに格納
    location_data_table.columns = [BRAND_CODE,LOCATION]

    df_merge = pd.merge(brand_data_table, location_data_table, on=[BRAND_CODE],how='left') #データフレームを結合

    create_point(df_merge) #ポイントをプロット

if __name__ == '__main__':
    get_finace_data()

このようにポイントがプロットされたら成功です!
f:id:sanvarie:20170110083034p:plain

属性もばっちり入っていますね。
f:id:sanvarie:20170110083105p:plain

やはり予想通り、東京に集中していますね。あとは神奈川、大阪などの都市圏にもかなり存在しているようです。そりゃたくさん人がいるわけだぁ。
f:id:sanvarie:20170110083307p:plain

f:id:sanvarie:20170110083351p:plain

「jsm」は株価もとってこれるので、東京の地価と企業の時価総額の関連性などを調べてみても面白そうですね。あとは東証一部だけではなく、全ての上場企業のデータを抽出し、都道府県ごとの人口と時価総額を比べてみても面白そうですね。以上、今回は「PythonとJSMで東証一部上場企業を可視化してみる」でした!