隗より始めよ

今後はいろいろ考え始めます。

【PYTHON】SBIから落としたCSVファイルを処理してみる(そしてシーズングラフを作ってみる)

f:id:mazarimono:20180821233543j:plain

さて、何の商品でも季節性というものを見たくなることがあります。

例えば、猛暑銘柄と呼ばれているものは本当に夏に上がるのかというのを見る時に、その季節性が一目瞭然な感じで見られると嬉しいでしょう。

某端末ではシーズングラフと確か呼ばれていたと思うのですが、私が使っている四季報やSBIにはそんなチャートがなかったので作ってみないといけないなぁと思っていましたが、実際に考えると毎年日数違うし面倒だなぁと思って、作らぬままでした。

しかし、本日気になる銘柄があったので作ってみたのですが、ちょっと僕には難しい部分があったので、相談がてらに記事にしてみようと思います。

データはSBIからcsvでダウンロードしたデータを使い、PCはwindows10です。作業はほぼPandasを使って行い、最後にmatplotlibでグラフにしています。

CSVを読み込み、処理する

さて、まずはCSVファイルを読み込みます。

df = pd.read_csv('kabuka.csv', encoding='shift-jis')

さてこのデータを見ると以下のようになっています。

f:id:mazarimono:20180821225454p:plain

データフレームのインデックスを日付にしたい。ということでそのままここに出てきた日付をインデックスに指定すると、下のようにうまく行きません。

f:id:mazarimono:20180821225647p:plain

というわけで、ちょっと日付データをいじくることになります。

df['date'] = list(map(lambda x: str(x)[:4] + '-' + str(x)[4:6] + '-' + str(x)[6:], df['日付']))
df.index = pd.to_datetime(df['date'])

f:id:mazarimono:20180821225902p:plain

すると上のようにうまく日付がインデックスに表示されます。しかし、日付が上が新しい日付となっているので、それを下が新しい日付に変更します。あと、使うのは終値だけなのですが、途中まで寂しい感じがするので、移動平均出来高をつけておきます。


日付の部分ですが、pandasで読むときに指定するとできるようです。キリンさんご指摘ありがとうございました。


df = df.sort_index().copy()
df = df.iloc[:, [4, 6, 9]].copy()

欲しいシーズングラフは、年別のデータを作るとできるので、年と日付のデータを付け加えてみましょう。

df['year'] = df.index.year
df['date'] = list(map(lambda x, y: str(x) + '-' + str(y), df.index.month, df.index.day))

f:id:mazarimono:20180821230745p:plain

まぁうまく行きそうにないけど、pivot_tableにすると以下のようになります。

table = pd.pivot_table(df, values=['終値'], index = ['date'], columns = ['year'])

f:id:mazarimono:20180821231454p:plain

まぁ、文字列ヤシこうなるわなーという感じです。やり直し。

作戦変更:いったんデータを分けて再び合体させる

日付では年ごとに休みも違うので、なんかかくかくするかもしれないので、それを日数にして、多少のずれには目をつぶるというつくり方の方が簡単なような気がしましたのでそうします。

いったん年ごとのデータに分けて、最初の日から番号をつけて、再び同じデータフレームにして返し、ピボットテーブルを作ればシーズングラフができそうです。

まずは何年のデータがあるかを確認します。

f:id:mazarimono:20180821232111p:plain

2010年~のデータがあることが分かったので、その年ごとにデータフレームを分けます。

f:id:mazarimono:20180821232227p:plain

そしてナンバリング用の関数を作り、各データごとに実行します。

f:id:mazarimono:20180821232429p:plain

そうしてできたデータを、合体させてピボットテーブルを作ります。そして季節性が見やすいように、各年の最初の値を100とするシーズンチャートを作ります。

data = pd.concat([d20101, d20111, d20121, d20131, d20141, d20151, d20161, d20171, d20181])
table = pd.pivot_table(data, values=['終値'], index = ['num'], columns = ['year'])
table2 = table / table.iloc[0, :] * 100
table2.plot(figsize=(18, 7), grid = True)

f:id:mazarimono:20180821232855p:plain

まとめ

何とか完成することができました。

しかし、各年ごとに分けてナンバリングしてまた合体させるというところを何とかうまくできないものかなぁと思っています。

もし教えてやろうという心の広い方がおられれば、ぜひコメント欄でもDMでも頂ければ幸いです。

このチャートちょっと季節性ありそうですねぇ。実はもうちょっと加工したいのですが、今日はこの辺で。