さて、何の商品でも季節性というものを見たくなることがあります。
例えば、猛暑銘柄と呼ばれているものは本当に夏に上がるのかというのを見る時に、その季節性が一目瞭然な感じで見られると嬉しいでしょう。
某端末ではシーズングラフと確か呼ばれていたと思うのですが、私が使っている四季報やSBIにはそんなチャートがなかったので作ってみないといけないなぁと思っていましたが、実際に考えると毎年日数違うし面倒だなぁと思って、作らぬままでした。
しかし、本日気になる銘柄があったので作ってみたのですが、ちょっと僕には難しい部分があったので、相談がてらに記事にしてみようと思います。
データはSBIからcsvでダウンロードしたデータを使い、PCはwindows10です。作業はほぼPandasを使って行い、最後にmatplotlibでグラフにしています。
CSVを読み込み、処理する
さて、まずはCSVファイルを読み込みます。
訂正(2018年9月23日)
下に既述したように、キリンさんからの指摘により読み込みを変更。
parse_datesというパラメーターで、文字列を日付に換えられる。
qiitaの記事では'Date'になっていたが、今試すと['Date']という形で記述する必要があった。
参考にしたのは以下のstack overflowの記事。
これで4行書いていたコードが1行になります!
df = pd.read_csv("kabuka.csv", parse_dates=['日付'], index_col='日付', encoding='shift-jis').sort_index()
df = pd.read_csv('kabuka.csv', encoding='shift-jis') df['date'] = list(map(lambda x: str(x)[:4] + '-' + str(x)[4:6] + '-' + str(x)[6:], df['日付'])) df.index = pd.to_datetime(df['date']) df = df.sort_index().copy()
さてこのデータを見ると以下のようになっています。
データフレームのインデックスを日付にしたい。ということでそのままここに出てきた日付をインデックスに指定すると、下のようにうまく行きません。
というわけで、ちょっと日付データをいじくることになります。
すると上のようにうまく日付がインデックスに表示されます。しかし、日付が上が新しい日付となっているので、それを下が新しい日付に変更します。あと、使うのは終値だけなのですが、途中まで寂しい感じがするので、移動平均と出来高をつけておきます。
日付の部分ですが、pandasで読むときに指定するとできるようです。キリンさんご指摘ありがとうございました。
日付のパースはこれが良さそうです。データの形を定義してあげたほうがいいですね。 https://t.co/rIIdUfdIdD
— fx-kirin (@fx_kirin) 2018年8月22日
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))
まぁうまく行きそうにないけど、pivot_tableにすると以下のようになります。
table = pd.pivot_table(df, values=['終値'], index = ['date'], columns = ['year'])
まぁ、文字列ヤシこうなるわなーという感じです。やり直し。
作戦変更:いったんデータを分けて再び合体させる
日付では年ごとに休みも違うので、なんかかくかくするかもしれないので、それを日数にして、多少のずれには目をつぶるというつくり方の方が簡単なような気がしましたのでそうします。
いったん年ごとのデータに分けて、最初の日から番号をつけて、再び同じデータフレームにして返し、ピボットテーブルを作ればシーズングラフができそうです。
まずは何年のデータがあるかを確認します。
2010年~のデータがあることが分かったので、その年ごとにデータフレームを分けます。
そしてナンバリング用の関数を作り、各データごとに実行します。
そうしてできたデータを、合体させてピボットテーブルを作ります。そして季節性が見やすいように、各年の最初の値を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)
まとめ
何とか完成することができました。
しかし、各年ごとに分けてナンバリングしてまた合体させるというところを何とかうまくできないものかなぁと思っています。
もし教えてやろうという心の広い方がおられれば、ぜひコメント欄でもDMでも頂ければ幸いです。
このチャートちょっと季節性ありそうですねぇ。実はもうちょっと加工したいのですが、今日はこの辺で。