Pandasの「ウィンドウ操作」をマスターしよう!詳細ガイドとサンプルコード集


このガイドでは、Pandasにおけるウィンドウ操作の概念と、その使用方法について詳細に解説します。

ウィンドウ操作とは?

ウィンドウ操作とは、データフレーム内の連続するデータのサブセット(ウィンドウ)を横断的に処理する操作です。各ウィンドウに対して、統計量や指標を計算し、結果を元のデータフレームに格納することができます。

例えば、株価データの分析において、過去一定期間における移動平均を計算したい場合、ウィンドウ操作が役立ちます。この場合、各ウィンドウは過去一定期間分の株価データで構成され、その平均値を計算して元のデータフレームに格納することができます。

Pandasにおける主要なウィンドウ操作関数

Pandasには、ウィンドウ操作を実行するための主要な関数として、以下の3つがあります。

  • expanding(): データフレームの最初から最後まで、増加するウィンドウサイズで関数を適用します。
  • resample(): 時間間隔に基づいてデータを分割し、各期間に対して関数を適用します。
  • rolling(): 指定されたウィンドウサイズでデータを分割し、各ウィンドウに対して関数を適用します。

これらの関数は、それぞれ異なる目的に適しており、状況に応じて使い分けることが重要です。

ウィンドウ操作の実行例

以下の例では、rolling()関数を使用して、時系列データの移動平均を計算する方法を示します。

import pandas as pd

# データの準備
data = pd.Series([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], index=pd.date_range('2023-01-01', periods=10))

# 過去3期間の移動平均を計算
data_ma = data.rolling(window=3).mean()

print(data_ma)

このコードを実行すると、以下の出力が得られます。

2023-01-01    NaN
2023-01-02    NaN
2023-01-03    2.0
2023-01-04    3.0
2023-01-05    4.0
2023-01-06    5.0
2023-01-07    6.0
2023-01-08    7.0
2023-01-09    8.0
2023-01-10    9.0

上記の例では、rolling()関数を使用して、過去3期間の移動平均を計算しています。window=3引数は、ウィンドウサイズを3に設定することを意味します。

Pandasのウィンドウ操作には、以下のような便利な機能が用意されています。

  • カスタム集計関数:独自の集計関数を定義してウィンドウに適用する
  • 重み付け:ウィンドウ内の各データポイントに重み付けを適用する
  • オフセット指定:ウィンドウをデータフレームの先頭または末尾からオフセットする

これらの機能を活用することで、より高度な分析や指標の計算が可能になります。



移動平均

以下のコードは、前述の例と同様に、時系列データの移動平均を計算します。

import pandas as pd

# データの準備
data = pd.Series([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], index=pd.date_range('2023-01-01', periods=10))

# 過去5期間の移動平均を計算
data_ma = data.rolling(window=5).mean()

print(data_ma)
2023-01-01    NaN
2023-01-02    NaN
2023-01-03    NaN
2023-01-04    NaN
2023-01-05    3.0
2023-01-06    4.0
2023-01-07    5.0
2023-01-08    6.0
2023-01-09    7.0
2023-01-10    8.0

指標計算

以下のコードは、ウィンドウ内のデータポイントの最大値、最小値、標準偏差を計算します。

import pandas as pd

# データの準備
data = pd.Series([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], index=pd.date_range('2023-01-01', periods=10))

# ウィンドウ内の最大値、最小値、標準偏差を計算
data_stats = data.rolling(window=3).agg({'max': 'max', 'min': 'min', 'std': 'std'})

print(data_stats)
               max  min  std
2023-01-01    NaN  NaN  NaN
2023-01-02    NaN  NaN  NaN
2023-01-03    3.0  1.0  1.0
2023-01-04    4.0  2.0  1.0
2023-01-05    5.0  3.0  1.0
2023-01-06    6.0  4.0  1.0
2023-01-07    7.0  5.0  1.0
2023-01-08    8.0  6.0  1.0
2023-01-09    9.0  7.0  1.0
2023-01-10   10.0  8.0  1.0

以下のコードは、過去2期間と未来2期間を含む5期間のウィンドウを使用して移動平均を計算します。

import pandas as pd

# データの準備
data = pd.Series([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], index=pd.date_range('2023-01-01', periods=10))

# 過去2期間と未来2期間を含む5期間の移動平均を計算
data_ma = data.rolling(window=5, center=False).mean()

print(data_ma)
2023-01-01    NaN
2023-01-02    NaN
2023-01-03    1.8
2023-01-04    2.6
2023-01-05    3.4
2023-01-06    4.2
2023-01-07    5.0
2023-01-08    5.8
2023-01-09    


ループによる処理

最も基本的な代替方法は、ループを使用してデータフレームを反復処理し、必要な計算を個別に実行する方法です。この方法は、柔軟性が高く、複雑な操作にも対応できます。

import pandas as pd

# データの準備
data = pd.DataFrame({'value': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]})

# 過去3期間の移動平均を計算
window_size = 3
moving_averages = []

for i in range(len(data)):
    if i < window_size:
        moving_averages.append(None)
    else:
        moving_averages.append(data['value'][i - window_size:i].mean())

data['moving_average'] = moving_averages

print(data)

このコードは、rolling()関数を使用せずに、過去3期間の移動平均を計算しています。

利点

  • 複雑な操作にも対応できる
  • 柔軟性が高い

欠点

  • コードが冗長になる
  • 処理速度が遅い

ベクトル化処理

NumPyなどのライブラリを使用して、ベクトル化処理を行う方法もあります。この方法は、ループ処理よりも高速で、コードも簡潔になります。

import pandas as pd
import numpy as np

# データの準備
data = pd.DataFrame({'value': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]})

# 過去3期間の移動平均を計算
window_size = 3
moving_averages = np.convolve(data['value'], np.ones(window_size)/window_size, mode='valid')

data['moving_average'] = moving_averages

print(data)

このコードは、np.convolve()関数を使用して、過去3期間の移動平均を計算しています。

利点

  • コードが簡潔になる
  • 処理速度が速い

欠点

  • 複雑な操作には対応できない
  • 柔軟性が低い

「dask」や「xarray」などのライブラリは、大規模なデータセットの処理に特化しており、ウィンドウ操作を含むさまざまな機能を提供しています。これらのライブラリは、Pandasよりも高速で効率的に処理を実行することができます。

利点

  • 高速で効率的な処理が可能
  • 大規模なデータセットの処理に適している
  • Pandasほど普及していない
  • 学習曲線がやや険しい