Blow Up by Black Swan

Python-CSVファイルからデータを取り、pandasでグラフを生成

今回は、前回の記事内容で作ったCSVファイルを基にpandasでグラフを生成するプログラミングです。

最近、徒然なるままに学習したことや自分で試行錯誤をしたプログラミングコードをあげていますが、今作ってみたいと思っているのは、日本の各仮想通貨取引所のAPIからBitcoinの価格情報を取り、一つのチャート上で各取引所の価格を表示するというものです。取引機能を備えさせるつもりないので、アービトラージを得ることが目的ではないですが、価格の全体的な動きを捉えたり、価格帯がおかしい取引所を見つけたりするのに有用ではないかと思っています。今回のコードではpandasが中心的な役割を果たしますが、pandasについては以前、pandasの公式ドキュメントに記載されている「10 minutes to pandas」をまとめた記事を書いていますので、興味があれば参考にして頂ければと思います。

1. 全体の構成

pythonのサードパーティーモジュールpandasがデータの取り扱いを極めて直感的かつ容易にしてくれるため、今回のコードは非常に簡単で短いです。ただし、コードを書く過程でよくわからず、かなりググったところがあるので、そこは補足しています。まず、全体の構成は以下になります。

 (1)csvファイルからデータを取る
 ->(2)グラフ表示用にDataFrameオブジェクトを整形する
 ->(3)タイムゾーンを設定し、時刻を修正する
 ->(4)グラフに表示する

全体の流れは以下のようになりますが、各部分が1行か2行と極めて短いです。次の章でコードを説明します。

2. コード

全体のコードは以下になります。

import pandas as pd


data_frame = pd.read_csv("/Users/nero/Documents/IT/cryptocurrency_API/test.csv", 
                 parse_dates=["date_time"])
df = data_frame[["price","date_time"]].set_index("date_time")
ts_utc = df.tz_localize('UTC')
tz_tokyo = ts_utc.tz_convert('Asia/Tokyo')
tz_tokyo.plot(figsize=(15,10))

先ほどの全体の構成とコードを照らし合わせると下記のようになります。

 (1)csvファイルからデータを取る: data_frame
 ->(2)グラフ表示用にDataFrameオブジェクトを整形する: df
 ->(3)タイムゾーンを設定し、時刻を修正する: tz_utc,tz_tokyo
 ->(4)グラフに表示する: tz_tokyo.plot()

(1)csvファイルからデータを取る
pandasのread_csvメソッドを利用してcsvファイルからデータを取り出します。pandasの非常に便利なところですが、open、closeメソッドを呼び出すことなく、read_csvメソッド1つでデータを取り出し、それをDataFrameオブジェクトに変換までしてくれます。また、もう1つ便利なのが、日付部分のデータをread_csvメソッドのparse_date引数に設定してあげると、勝手に日付を解析してくれます。pandasは本当に痒いところに手が出るように設定されているなという印象を受けます。これで、pandasの他のメソッドが扱える状態になりました。

(2)グラフ表示用にDataFrameオブジェクトを整形する
そして、DataFrameオブジェクトをグラフの表示に合わせて設定します。今回は、X軸を日付、Y軸を価格としているので、set_indexメソッドを用いて日付をインデックス、つまりX軸に指定しています。今回、前回の記事で作成したcsvファイルを利用しており、そこではデータ取得用にid情報も入れていますが、グラフの表示においては不必要です。

ここら辺の設定の簡略さもpandasの魅力だと思います。なお、二重の角括弧を利用していますが、ここは当初何をしているかわからず色々調べた部分になりますので、コードに関する補足説明の部分で扱っています。

(3)タイムゾーンを設定し、時刻を修正する: tz_utc,tz_tokyo
bitflyerのAPIから情報を取得した際、そこに記載されている時刻はUTC(協定世界時)と言われる時刻になります。これはイギリス、ロンドンの時刻に掃討しており、そこから9時間早い日本時刻に直した方がよりチャートなどが理解しやすくなります。そのため、この時刻を修正するコードを入れています。

まず、bitflyerAPIから取得した時刻はjson解析などの過程で単なる時刻になり、タイムゾーンのなどの付随情報を持っていません。これは、pythonで時刻オブジェクトを扱うときに知る必要がある、naiveとawareという2つの時刻オブジェクトに関連する部分です。

naiveはその意味どおり、純粋な時間表記だけであり、awareはそこにタイムゾーンやサマータイムなどの他の時刻や地域などと相対化できる情報を保持した時刻オブジェクトになります。ts_utcの部分では、単純な時刻にタイムゾーン情報を加えてあげ、naiveな時刻オブジェクトからawareな時刻オブジェクトに変換します。そして、tz_convertメソッドを用いて東京にタイムゾーンが設定され、東京時刻表記になるようにしています。

通常、この部分はpythonの標準モジュールや関連モジュールなどを別途呼び出して処理する必要があるのですが、、pandasでは自身のパッケージ内で完結できるように設定されています。pandasではない、標準モジュールなどを利用したタイムゾーンの変更処理などについては過去記事にしていますので、参考にして頂ければと思います。

●(4)グラフに表示する: tz_tokyo.plot()
基本的なx軸、y軸を指定したdfの時点でグラフ表示は可能です。このグラフ表示をするために利用されるのが、plotメソッドです。内部的にmatoplotlibを利用しているようです。また、引数に指定されているfigureは、グラフのサイズです。figureは設定されていなくてもグラフは表示されます。これで、csvデータのグラフ表記が完成します。

チャートイメージ図

下記のようなグラフが出来上がります。

3. コードに関する補足説明

ここでは、この数行のコードを作るときに私が理解に手間取った部分を説明します。

3-1. pandasのDataframe、[](角括弧)演算子

まず一つ目は[](角括弧)演算子についてです。これは、「かくがっこ」と読みます。変数dfで二重の角括弧が設置されていますが、当初、リストの中のリストかリストの中のdict型から情報を取得するための、亜種の方法かと思いました。しかし、どうやら色々調べたところ、私の目論見は全く外れており、これは角括弧演算子の中にリストで値を取得したものだということでした。pandasでは。DataFrameオブジェクトを格納した変数において、角括弧演算子を用いることで、指定したカラムの値を取得することができます。例えば以下のようなDataFrameオブジェクトがあるとします。

import pandas as pd
import numpy as np

dates = pd.date_range('20130101', periods=8)
df = pd.DataFrame(np.random.randn(8, 4), index=dates, columns=['A', 'B', 'C', 'D'])
df

戻り値

 ABCD
2013-01-010.7742361.6158041.577247-0.876187
2013-01-020.079045-0.0778220.707507-0.626046
2013-01-03-1.609346-0.371870-0.1053291.727113
2013-01-040.6586300.596951-0.638654-0.431703
2013-01-05-1.1216690.591910-0.618029-0.173722
2013-01-061.478463-0.3311180.5177061.301466
2013-01-07-1.154572-0.122319-0.2942191.438894
2013-01-080.5908672.989774-0.350753-0.280739

そして、ここから角括弧演算子でカラムを指定すると以下のように値が返ってきます。

x = df["A"]
x

戻り値

2013-01-01    0.774236
2013-01-02    0.079045
2013-01-03   -1.609346
2013-01-04    0.658630
2013-01-05   -1.121669
2013-01-06    1.478463
2013-01-07   -1.154572
2013-01-08    0.590867
Freq: D, Name: A, dtype: float64

そして、この指定するカラムは、複数指定することができ、そのときの指定に使われるがリストです。そのため、角括弧演算子が二重になっているように見えています。ただ実際には、外側が角括弧、中がリストというただそれだけです。上記のDataFrameオブジェクトを用いてリストによる複数のカラムの指定を試しています。

a =df[["A","C"]]
a

戻り値

 AC
2013-01-010.7742361.577247
2013-01-020.0790450.707507
2013-01-03-1.609346-0.105329
2013-01-040.658630-0.638654
2013-01-05-1.121669-0.618029
2013-01-061.4784630.517706
2013-01-07-1.154572-0.294219
2013-01-080.590867-0.350753

また、この方法を利用することで、カラムのコピーや既存のカラムに手を加えた新たなカラムの作成ができます。以下はカラムのコピーの例です。

df[["X","Y"]] = df[["A","B"]]
df

戻り値

 ABCDXY
2013-01-010.7742361.6158041.577247-0.8761870.7742361.615804
2013-01-020.079045-0.0778220.707507-0.6260460.079045-0.077822
2013-01-03-1.609346-0.371870-0.1053291.727113-1.609346-0.371870
2013-01-040.6586300.596951-0.638654-0.4317030.6586300.596951
2013-01-05-1.1216690.591910-0.618029-0.173722-1.1216690.591910
2013-01-061.478463-0.3311180.5177061.3014661.478463-0.331118
2013-01-07-1.154572-0.122319-0.2942191.438894-1.154572-0.122319
2013-01-080.5908672.989774-0.350753-0.2807390.5908672.989774

そして、カラムの追加です。

df[["A/2","B/2"]] = df[["A","B"]]/2
df

戻り値

 ABCDXYA/2B/2
2013-01-010.7742361.6158041.577247-0.8761870.7742361.6158040.3871180.807902
2013-01-020.079045-0.0778220.707507-0.6260460.079045-0.0778220.039522-0.038911
2013-01-03-1.609346-0.371870-0.1053291.727113-1.609346-0.371870-0.804673-0.185935
2013-01-040.6586300.596951-0.638654-0.4317030.6586300.5969510.3293150.298475
2013-01-05-1.1216690.591910-0.618029-0.173722-1.1216690.591910-0.5608340.295955
2013-01-061.478463-0.3311180.5177061.3014661.478463-0.3311180.739231-0.165559
2013-01-07-1.154572-0.122319-0.2942191.438894-1.154572-0.122319-0.577286-0.061160
2013-01-080.5908672.989774-0.350753-0.2807390.5908672.9897740.2954331.494887

以上がpandasの角括弧演算子の使い方です。

4. まとめ

以上が私が今回作成したpandasからデータを取り、グラフを生成するコードです。pandasの扱い方がわかっていれば、非常に簡単でした。ただし、複数の仮想通貨取引所の価格を一斉に表記する場合、どのようにコードを書くのかについてはまだ勉強ですので、引き続き挑戦していきたいと思います。

読んでくださった方、どうもありがとうございます。

5. 参考サイト

今回の参考サイトは以下になります。メインに参考にしたサイトはpandasの公式ドキュメントです。