時系列データの分析をする際に「移動平均」という言葉を聞いたことがあると思います。
今回は移動平均とはなにかということと、Pandasで移動平均の求め方について取り上げます。
移動平均とは
株価や気温など、時間の推移によって細かく値が変化するデータは、その変動の細かさ故に全体の傾向を掴むのが難しいケースもしばしばあります。そこで登場するのが「移動平均」です。移動平均を求めることでデータの変化をより滑らかにし、全体の傾向がより掴みやすくなります。
下図は米国株価指数の1つであるS&P500の日時チャートです。
ここに移動平均を重ねてみると、より滑らかになっていることがわかります。株価や株価指数は20日移動平均や50日移動平均で表すことが多いです。今回は20日移動平均を重ねています。
移動平均の求め方
移動平均の算出方法にはいくつかありますが、最もシンプルなのは単純相加平均です。単純相加平均は、中心の値から前後いくつかの値から平均値を算出します。
前後何個のデータから平均を算出するかというのは状況によって適切に決める必要があります。データの個数は「n項移動平均」といったように表します。上の株価の例だと、20日移動平均とは前後併せて20日分(1日1件)のデータの平均をとったものです。
5項移動平均を求める式は以下の通りです。
偶数個のデータで移動平均を求める場合は、中心項から最も離れている項2つを0.5でかけたうえで平均を算出します。
Pandasで移動平均を求める
pandasで移動平均を求めるには、rolling()を用います。rolling()は窓関数を適用する関数ですが、単純相加平均の算出も可能です。
今回はS&P500のデータを使っていきます。
df = pd.read_csv("C:/Python/data/sp500_index.csv", parse_dates=[0])
df = df[df["Date"]>= dt.datetime(2020,1,1)].reset_index(drop=True)
基本の使い方
基本的にはrolling().mean()を用いることで単純相加平均を求めることができます。
必須の引数としてwindowを指定します。これは、隣り合ういくつの値から統計量を求めるかを指定するパラメータです。以下で、window=3の結果を見てみます。
df3 = df.rolling(3).mean()
結果の格納位置を変更する
デフォルトでは、Windowで指定した範囲のうち最後の位置に計算結果が格納されます([0], [1], [2]の計算結果は[2]に格納される)。center=Trueとすることで、Windowの範囲の中心位置に結果を格納することができます([0], [1], [2]の計算結果は[1]に格納される)。
このとき、先頭および末尾でデータ数が足りない位置はNaNとなります。
df3 = df.rolling(3, center=True).mean()
株価と移動平均のグラフを描いてみる
株価と移動平均をグラフにプロットしてみます。冒頭の例にもあるような、S&P500とその20日移動平均を重ねて描画します。
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
df = pd.read_csv("C:/Users/dadad/Python/data/sp500_index.csv", parse_dates=[0])
df = df[df["Date"]>= dt.datetime(2020,1,1)].reset_index(drop=True)
#移動平均算出
df20 = df.rolling(20).mean()
fig, ax = plt.subplots(figsize=(7,3))
ax.plot(df["Date"], df["S&P500"] )
ax.plot(df["Date"], df20["S&P500"])
ax.legend(["S&P500", "20日移動平均"], prop={"family":"MS Gothic"})
#x軸ラベルのフォーマット
plt.gca().xaxis.set_major_formatter(mdates.DateFormatter("%y/%m"))
まとめ
移動平均とはなにかということと、Pandasで移動平均の求め方について取り上げました。rolling()は平均以外にも、sum()やmin()、max()といった集計関数も使用できます。
時系列データを移動平均で分析するケースもあると思うので、是非活用してください。
ではでは👋