【Pandas】移動平均を求める -rolling()

時系列データの分析をする際に「移動平均」という言葉を聞いたことがあると思います。

今回は移動平均とはなにかということと、Pandasで移動平均の求め方について取り上げます。

移動平均とは

株価や気温など、時間の推移によって細かく値が変化するデータは、その変動の細かさ故に全体の傾向を掴むのが難しいケースもしばしばあります。そこで登場するのが「移動平均」です。移動平均を求めることでデータの変化をより滑らかにし、全体の傾向がより掴みやすくなります。

下図は米国株価指数の1つであるS&P500の日時チャートです。

S&P500指数

ここに移動平均を重ねてみると、より滑らかになっていることがわかります。株価や株価指数は20日移動平均や50日移動平均で表すことが多いです。今回は20日移動平均を重ねています。

20日移動平均

移動平均の求め方

移動平均の算出方法にはいくつかありますが、最もシンプルなのは単純相加平均です。単純相加平均は、中心の値から前後いくつかの値から平均値を算出します。

前後何個のデータから平均を算出するかというのは状況によって適切に決める必要があります。データの個数は「n項移動平均」といったように表します。上の株価の例だと、20日移動平均とは前後併せて20日分(1日1件)のデータの平均をとったものです。

5項移動平均を求める式は以下の通りです。

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)
sp500_index.csv

基本の使い方

基本的にはrolling().mean()を用いることで単純相加平均を求めることができます。

必須の引数としてwindowを指定します。これは、隣り合ういくつの値から統計量を求めるかを指定するパラメータです。以下で、window=3の結果を見てみます。

df3 = df.rolling(3).mean()
df3 = df.rolling(3).mean()df3
df3
[0], [1], [2]の計算結果(今回は平均)は[2]に格納されます。先頭2つ([0], [1])は3つ分のデータがないため計算されず、NaNが返されます。

結果の格納位置を変更する

デフォルトでは、Windowで指定した範囲のうち最後の位置に計算結果が格納されます([0], [1], [2]の計算結果は[2]に格納される)。center=Trueとすることで、Windowの範囲の中心位置に結果を格納することができます([0], [1], [2]の計算結果は[1]に格納される)。

このとき、先頭および末尾でデータ数が足りない位置はNaNとなります。

df3 = df.rolling(3, center=True).mean()
df3 = df.rolling(3, center=True).mean()
df3

株価と移動平均のグラフを描いてみる

株価と移動平均をグラフにプロットしてみます。冒頭の例にもあるような、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"))
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()といった集計関数も使用できます。

時系列データを移動平均で分析するケースもあると思うので、是非活用してください。

ではでは👋