Pandas DataFrameで時系列データの変化率を分析:pct_change()の使い方を徹底解説


pandas.DataFrame.pct_change() メソッドは、Pandas DataFrame の列における要素間の割合変化を計算します。これは、時系列データの変化率を分析する際に特に有用です。

構文

DataFrame.pct_change(periods=1, fill_method='pad', limit=None)

引数

  • limit: 連続する欠損値の数を指定します。この数を超えると、計算が停止されます。
  • fill_method (デフォルト: 'pad'): 欠損値をどのように処理するかを指定します。
    • 'pad': 前の値で埋めます。
    • 'bfill': 次の値で埋めます。
    • 'ffill': 最初の値で埋めます。
    • 'nearest': 最も近い値で埋めます。
  • periods (デフォルト: 1): 現在の値と比較する前の要素の数。

戻り値

新しい DataFrame を返します。元の DataFrame と同じ形状を持ち、各列には割合変化が格納されます。

以下の例では、株価データの DataFrame を作成し、pct_change() メソッドを使用して終値の変化率を計算します。

import pandas as pd

# 株価データを作成
data = {'日付': ['2020-01-01', '2020-01-02', '2020-01-03', '2020-01-04'],
        '終値': [100, 105, 110, 108]}
df = pd.DataFrame(data)

# 終値の変化率を計算
df['変化率'] = df['終値'].pct_change()

print(df)

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

       日付     終値  変化率
0 2020-01-01  100.000000    0.000000
1 2020-01-02  105.000000    0.050000
2 2020-01-03  110.000000    0.047619
3 2020-01-04  108.000000  -0.018182
  • 変化率を百分率で表示するには、* 100 を乗算します。
  • 欠損値を含む列に対しては、欠損値が処理方法によって置き換えられます。
  • pct_change() メソッドは、列ごとに計算されます。


例 1: 期間を指定して変化率を計算

この例では、株価データの DataFrame を作成し、1日前との終値の変化率を計算します。

import pandas as pd

# 株価データを作成
data = {'日付': ['2020-01-01', '2020-01-02', '2020-01-03', '2020-01-04', '2020-01-05'],
        '終値': [100, 105, 110, 108, 112]}
df = pd.DataFrame(data)

# 1日前との終値の変化率を計算
df['変化率'] = df['終値'].pct_change(periods=1)

print(df)
       日付     終値  変化率
0 2020-01-01  100.000000    NaN
1 2020-01-02  105.000000    0.050000
2 2020-01-03  110.000000    0.047619
3 2020-01-04  108.000000  -0.018182
4 2020-01-05  112.000000    0.037037

例 2: 欠損値を埋めて変化率を計算

この例では、株価データの DataFrame を作成し、欠損値を前日の値で埋めて1日前との終値の変化率を計算します。

import pandas as pd

# 株価データを作成
data = {'日付': ['2020-01-01', '2020-01-02', '2020-01-03', '2020-01-04', '2020-01-05'],
        '終値': [100, 105, 110, np.nan, 112]}
import numpy as np
df = pd.DataFrame(data)

# 欠損値を前日の値で埋める
df['終値'].fillna(method='bfill', inplace=True)

# 1日前との終値の変化率を計算
df['変化率'] = df['終値'].pct_change(periods=1)

print(df)
       日付     終値  変化率
0 2020-01-01  100.000000    NaN
1 2020-01-02  105.000000    0.050000
2 2020-01-03  110.000000    0.047619
3 2020-01-04  110.000000    0.000000
4 2020-01-05  112.000000    0.018182

例 3: 期間を指定して複数列の変化率を計算

この例では、複数の列を持つ商品価格データの DataFrame を作成し、過去2日間の価格の変化率を計算します。

import pandas as pd

# 商品価格データを作成
data = {'日付': ['2020-01-01', '2020-01-02', '2020-01-03', '2020-01-04'],
        '商品A': [100, 102, 105, 104],
        '商品B': [95, 98, 101, 99]}
df = pd.DataFrame(data)

# 過去2日間の


diff() と div() の組み合わせ

  • 欠点:
    • 欠損値の処理が必要
    • コードが冗長になる可能性がある
  • 利点:
    • シンプルで分かりやすい構文
    • 柔軟性が高い
def pct_change_with_diff_div(df, periods=1, fill_method='ffill'):
    df_shifted = df.shift(periods=periods, fill_method=fill_method)
    return (df - df_shifted) / df_shifted

カスタム関数

  • 欠点:
    • 開発とテストが必要
  • 利点:
    • 特定のニーズに合わせた処理が可能
    • コードをより簡潔に記述できる
def pct_change_custom(df, periods=1, fill_method='ffill'):
    previous = df.shift(periods=periods, fill_method=fill_method)
    change = df - previous
    return change / previous

NumPy を使用する

  • 欠点:
    • Pandas データフレームとのやり取りが必要
    • Pandas の機能にアクセスできない
  • 利点:
    • 高速処理
    • ベクター化が可能
import numpy as np

def pct_change_numpy(df, periods=1, fill_method='ffill'):
    filled_df = df.fillna(method=fill_method)
    previous = np.roll(filled_df.values, shift=periods, axis=0)
    change = filled_df.values - previous
    return change / previous
  • scikit-learn: preprocessing.ImputerStandardScaler を使用して前処理を行い、LinearRegression モデルで変化率を計算
  • statsmodels: stattools.add_roll_pctchange 関数を提供

最適な方法の選択

最適な方法は、データ、ニーズ、スキルセットによって異なります。

  • 統計モデリングの知識がある場合は、statsmodels や scikit-learn などのライブラリを活用するのも良い選択肢です。
  • 高速処理が必要な場合は、NumPy を使用する方が良いでしょう。
  • 柔軟性とカスタマイズ性を重視する場合は、カスタム関数を検討してください。
  • シンプルで分かりやすい方法が必要な場合は、diff()div() の組み合わせがおすすめです。