日付毎の株価データをpandasで銘柄ごとのデータに作り直す方法【pythonでシストレ】

スクレイピング 等で取得した日付毎の株価データを銘柄毎に整理し直す方法を紹介します。

 

 

株価データの取得は日付毎の方が効率的です。例えば、とある日の株価を500銘柄分取得したいとします。

 

この時、銘柄毎に株価データをスクレイピング しようとすると500回処理が必要ですが、全銘柄のその日の株価データが全てまとめて入った日付ごとに管理されたデータがあれば、一回の処理で希望する日の全てのデータを取得できます。(その代わり3年分の株価が欲しい時は三年分のスクレイピング 処理が必要になる)

 

 

スクレイピング は、sleepの設定等をちゃんとしてやらないと相手のサイトに負荷をかけてしまうため、極力最小限の処理で留めておきたいものです。そうすると、全株価データが入った日付毎のデータを毎日一回取得するというのが良いということになります。

 

 

しかし、実際に株価分析をする際は、銘柄毎にデータを整理しておきたいケースもあると思います。

 

この記事ではpythonのpandasモジュールを使って、日付ごとのデータを銘柄毎のデータへ変換する方法を紹介します。

 

・・・しかし、この記事で紹介する方法はとても効率が悪いです。もっとスマートなやり方があるはずなので、あまり真似しない方が良いかもしれません。

スポンサーリンク
スポンサーリンク

pandasで全ての日付データを結合

株価データは日付毎のCSVファイルとし、1つのフォルダにまとめられていることを想定しています。

import pandas as pd
import glob
import datetime

data_path='株価データCSVがまとめられているディレクトリ'
csvfile=glob.glob(data_path+'*.csv')
dlist=[]

for f in csvfile:
    dlist.append(pd.read_csv(f,header=None,encoding="shift-jis"))

df=pd.concat(dlist) 

glob.globでフォルダ内の全CSVファイルの名前をcsvfileという名前でリスト化。

 

ディレクトリ内の全てのCSVデータではなく、特定の期間のみのCSVデータを使いたいときは、ファイル名の規則性などを利用して、抽出するファイル名を独自に指定する必要があります。

 

 

リスト化したCSVファイルを全てpd.read_csvでpandasデータフレームにして、appendメソッドでリスト化します。

 

イメージとしては

[2/1CSV分のpandasデータフレーム]

[2/2CSV分のpandasデータフレーム]

[2/3CSV分のpandasデータフレーム]

・・・

って感じのリストです。このサンプルコードではdlistがこれに該当します。

pd.read_csvの引数header=Noneは、先頭の行を列インデックスにしない設定。

引数のencodingはshift-jisにしておかないと、csvファイルの中に日本語が混じっているときに文字化けしたり、エラーが出たりする。

for f in csvfile:
    dlist.append(pd.read_csv(f,header=None,encoding="shift-jis"))

 

dlistにまとめた全日付のpandasデータフレームをpd.concatメソッドで結合してやります。

df=pd.concat(dlist)

この処理は時間がかかります。

 

というのも、日本株式の全銘柄数は3500以上。日付データ1つに3500の銘柄データがあり、そのデータを例えば5年分まとめようとすると、一年の営業日を240として

 

3,500×240×5=4,200,000

 

となり、420万個ものデータが作られます。処理を早くするのなら、上で述べたように無駄な日付データや銘柄を抽出するデータから除外するべきです。

pandasのマルチインデックス で銘柄毎にソート

上の例で取得した株価データは、

「日付」「銘柄コード」「始値」「高値」「安値」「終値」の6列のデータだと考えます。

 

dfが上の処理で結合した後のデータです。

df['日付']=pd.to_datetime(df['日付'])
 stock_path='銘柄毎に整理したデータを保存するディレクトリ'
date_start=start
date_finish=finish

df=df[df['日付']>=date_start]
df=df[df['日付']<=date_finish]


code='抽出したい銘柄コード'
df2=df[df['銘柄コード']== code]
df2=df2.sort_values('日付').reset_index(drop=True)
df2.columns=["date","code","open","high","low","close"]
df2.to_csv(save_path+str(code)+'.csv')
まずは、日付列のデータ型をdatatime型に変換しておきます。すでに変換済みなら処理不要。変換済みかどうかは、df.dtypesでデータ型を表示すれば確認可能。
df['日付']=pd.to_datetime(df['日付'])

欲しい日付データの範囲を指定します。

start=’2010/1/1′

finish=’2018/12/31′

とすれば9年分の株価データを指定するになります。日付をdatetime型にしておかないとここでエラーが出たり、正しく処理されなかったりします。

date_start=start
date_finish=finish

df=df[df['日付']>=date_start]
df=df[df['日付']<=date_finish]

 

銘柄コードでデータを抽出して、sort_valuesで日付順でソート。おまけでreset_index(drop=True)でインデックスを振り直す。(しなくてもOK)

 

文字化けエラーの可能性を潰すためdf2.columnsで列名を全て英語表記に変更し、最後にto_csvメソッドで銘柄コード.csvのファイル名で保存します。

code='抽出したい銘柄コード'
df2=df[df['銘柄コード']== code]
df2=df2.sort_values('日付').reset_index(drop=True)
df2.columns=["date","code","open","high","low","close"]
df2.to_csv(save_path+str(code)+'.csv')

かなり省略しましたが、以上が自分が行なっている処理のサンプルです。

株価データを触る際は、マーケットの確認をしておく

最後に、1つだけ個人的に苦慮した点を1つだけ紹介しておきます。

 

 

それはマーケットの指定です。マーケットっていうのは、いわゆる「東証一部」「東証二部」「マザーズ」・・・ってやつです。

 

特にややこしかったのは、「大阪証券取引所」「札幌証券取引所」「名古屋証券取引所」。訳して「大証」「札証」「名証」。

 

 

何がややこしいかというと、例えば東証一部と大証の2箇所で上場している銘柄があると、銘柄コードで抽出するとデータが2つ抽出されてしまうことがあるんです。もし重複してデータが抽出されるようなら

df=df[df['市場']!='大証']

みたいな感じで、大証で上場していた銘柄をデータから除外する処理が必要です。

 

*大証は今では個別株の取引所はありませんが、過去のデータを探すと出てきます。

 

 

このほか、株式分割・併合が適切に反映されているかも確認しておく必要があります。プログラムを作るようになると自然と株式市場についても詳しくなりますね。

 

 

本当は、SQLなどのデータベースを利用するともっと簡単なんでしょうが、SQLを覚える気力が今の私にはありません・・・(涙。

コメント