【超簡単】pythonで移動平均を計算するには?(pandas、numpy)

当ページのリンクには広告が含まれています。

時系列データを使った分析では、しばしば移動平均を計算する必要に迫られます。

python には移動平均を簡単に計算できる方法が用意されていますので、今回はそれについて解説します。

pandas と numpy のどちらでも可能なので、両方を載せておきます。

目次

pandasで移動平均

pandas で移動平均を計算するには rolling メソッドを使います。

  rolling(データ個数).mean()

例えば、5個のデータで移動平均を求める場合は、次の様に記述します。

import pandas as pd

data = pd.Series([1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0])

print('移動平均',data.rolling(5).mean())

結果は以下の通りです。

今回は5個のデータで移動平均を算出しているため、データが5個揃うまでは平均値が計算がされず、その結果 NaN が先頭に埋められています。

rolling には、続けて apply(関数) を指定することで、任意の関数を適用することが可能です。

下記の様rに、平均を求める関数を用意することで、同じことが実現できます。

def func(x):
    return x.mean()

print(data.rolling(5).apply(func))

#又はラムダ式を使って下記の様にも書ける
print(data.rolling(5).apply(lambda x: x.mean()))

numpy で移動平均

numpy で移動平均を計算する場合、convoluve メソッドを使います。

 convolve(データ,np.ones(個数), mode='valid') / 個数

もともと、この convoluve メソッドは畳み込み用のメソッドなのですが、移動平均でも利用されています。

np.ones() は引数で指定した個数の配列を作るメソッドで、値は全て1.0 が格納されます。

convoluve は、第一引数で渡されたデータと np.ones() で作成した配列の値で内積の和を順次計算していくので、np.onse()の値を個数分で割るか、convoluve の戻り値を個数分で割ることで、結果的に移動平均を求めることが出来ます。

pandas の移動平均では、先頭の部分は値が揃わないため NaN が出力されていましたが、convoluveでは mode='valid' を指定することで、値が揃った位置から計算をしてくれるため、先頭の NaN は入りません。

以下は、5個の移動平均を求めるサンプルです。

import numpy as np

data = np.array([1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0])

#np.ones()の値を個数で割る方法
print('移動平均',np.convolve(data,np.ones(5)/5, mode='valid'))

#convolveが返す結果を個数で割る方法
print('移動平均',np.convolve(data,np.ones(5), mode='valid') / 5)

結果は次のようになります。

移動平均 [3. 4. 5. 6. 7.]

pandas の時と同じ答えが返ってきています。

bottleneck による移動平均

bottleneck というモジュールにも移動平均のメソッドが用意されています。

これは

import numpy as np
import bottleneck as bn

data = np.array([1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0])

print('移動平均',bn.move_mean(data, window=5))

結果は以下の通りです。

移動平均 [nan nan nan nan 3. 4. 5. 6. 7.]

どれが一番速いか

今回紹介した方法で、どれが一番速いかを簡単に調べてみました。

その結果、move_mean がダントツで、次に convolve 、3番目は rolling.mean、一番遅いのはrolling.apply という結果でした。

メソッド処理時間(秒)rolling.meanを1とした倍率
rolling.mean0.0011301
rolling.apply0.0022870.49
convolve0.00003136.67
move_mean0.000006174.88

今回は非常に小さなデータで試したので、あくまでも参考値として見ていただければと思います。


#rolling.mean
    data = pd.Series([1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0])
    data.rolling(5).mean()

#rolling.apply
    data = pd.Series([1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0])
    data.rolling(5).apply(lambda x: x.mean())

#convolve
    data = np.array([1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0])
    np.convolve(data,np.ones(5), mode='valid') / 5

#move_mean
    data = np.array([1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0])
    bn.move_mean(data, window=5)

まとめ

今回は移動平均について、pandas で2 種類 、nampy で1 種類 、bottleneck で1 種類 の合計4種類について、具体的な使い方を解説致しました。

処理速度についても、bottleneckの move_mean() が最も高速でしたが、よほど大量のデータに対して移動平均を何度も計算するような場合でなければ、pandas でも全く問題が無いと思います。

今回の記事が皆さんのお役に立てれば幸いです。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

目次