Pandas Series.backfillの極意!欠損値補完をマスターして時系列データ分析を制覇


pandas.Series.backfill は、欠損値(NaN)を前の有効値で埋める Pandas のメソッドです。時系列データの分析などでよく用いられ、連続した欠損値を効率的に補完することができます。

使い方

import pandas as pd

# データ作成
s = pd.Series([1, np.nan, 3, 4, np.nan, 6])

# backfill で欠損値を前の値で埋める
s_backfilled = s.backfill()

print(s_backfilled)

出力

0    1.000000
1    1.000000
2    3.000000
3    4.000000
4    4.000000
5    6.000000
dtype: float64

オプション

  • method: 埋める方法(デフォルトは 'nearest' で最近傍値、'linear' で線形補間)
  • limit: 前方向に遡る最大欠損値数(デフォルトは None で制限なし)
# limit オプションで前方向に2つまで遡る
s_backfilled_limit = s.backfill(limit=2)

# method オプションで線形補間
s_backfilled_linear = s.backfill(method='linear')
  • fillna メソッドと異なり、backfill は前の有効値のみを参照するため、データの連続性が重要となる時系列データに適しています。
  • inplace オプションを True に設定すると、元の Series を直接変更します。
  • 販売データのトレンド分析
  • 気象データの連続性を保ちながら分析
  • 株価データの欠損値を補完


時系列データの欠損値補完

import pandas as pd
import numpy as np

# 時系列データを作成
dates = pd.date_range('2020-01-01', periods=10)
values = np.random.randn(10)
s = pd.Series(values, index=dates)

# 欠損値をランダムに挿入
s.loc[np.random.choice(s.index, 3)] = np.nan

# backfill で欠損値を前の値で埋める
s_backfilled = s.backfill()

print(s_backfilled)

複数列の DataFrame の欠損値補完

import pandas as pd
import numpy as np

# データを作成
data = {'A': [1, np.nan, 3, 4, np.nan],
        'B': [2, 4, np.nan, 3, 1],
        'C': [np.nan, 1, 2, 5, 3]}
df = pd.DataFrame(data)

# backfill で欠損値を前の値で埋める
df_backfilled = df.backfill()

print(df_backfilled)

このコードでは、複数の列を持つ DataFrame の欠損値を backfill で補完しています。

limit オプションの使用

import pandas as pd
import numpy as np

# データを作成
dates = pd.date_range('2020-01-01', periods=10)
values = np.random.randn(10)
s = pd.Series(values, index=dates)

# 欠損値をランダムに挿入
s.loc[np.random.choice(s.index, 5)] = np.nan

# limit オプションで前方向に2つまで遡る
s_backfilled_limit = s.backfill(limit=2)

print(s_backfilled_limit)

このコードでは、limit オプションを使用して、前方向に遡る最大欠損値数を 2 に制限しています。

method オプションの使用

import pandas as pd
import numpy as np

# データを作成
dates = pd.date_range('2020-01-01', periods=10)
values = np.random.randn(10)
s = pd.Series(values, index=dates)

# 欠損値をランダムに挿入
s.loc[np.random.choice(s.index, 5)] = np.nan

# method オプションで線形補間
s_backfilled_linear = s.backfill(method='linear')

print(s_backfilled_linear)

このコードでは、method オプションを使用して、欠損値を線形補間しています。

import pandas as pd
import numpy as np

# データを作成
dates = pd.date_range('2020-01-01', periods=10)
values = np.random.randn(10)
s = pd.Series(values, index=dates)

# 欠損値をランダムに挿入
s.loc[np.random.choice(s.index, 5)] = np.nan

# inplace オプションで元の Series を変更
s_backfilled_inplace = s.backfill(inplace=True)

print(s)  # 欠損値が補完されていることを確認


fillna メソッド

fillna メソッドは、欠損値を一意の値で置き換える汎用的な方法です。backfill と同様に、前の有効値を使用できますが、以下の点に注意が必要です。

  • 方向を指定できないため、時系列データ以外のデータには適していない場合があります。
  • 前の有効値が存在しない場合、指定した値で置き換えられます。
import pandas as pd
import numpy as np

# データ作成
s = pd.Series([1, np.nan, 3, 4, np.nan, 6])

# fillna で欠損値を前の値で埋める
s_filled = s.fillna(method='bfill')

print(s_filled)

利点

  • 方向を指定する必要がない
  • 欠損値を任意の値で置き換えられる

欠点

  • 時系列データ以外のデータには適していない場合があります
  • 前の有効値が存在しない場合、指定した値で置き換えられる

interpolate メソッド

interpolate メソッドは、欠損値を補間する汎用的な方法です。linear オプションを使用して線形補間を行うことで、backfill と同様の効果を得ることができます。

import pandas as pd
import numpy as np

# データ作成
s = pd.Series([1, np.nan, 3, 4, np.nan, 6])

# interpolate で欠損値を線形補間
s_interpolated = s.interpolate(method='linear')

print(s_interpolated)

利点

  • 線形補間以外にも様々な補間方法を選択できる

欠点

  • backfill よりも計算コストがかかる場合がある

カスタム関数

より複雑なロジックが必要な場合は、カスタム関数を作成することができます。例えば、欠損値を前の有効値と次の有効値の平均で置き換えるような関数を作成できます。

import pandas as pd

def my_backfill(series):
    """
    欠損値を前の有効値と次の有効値の平均で置き換える

    Args:
        series (pd.Series): データ

    Returns:
        pd.Series: 欠損値が補完されたデータ
    """
    for i in range(len(series)):
        if pd.isna(series.iloc[i]):
            if i == 0 or pd.isna(series.iloc[i - 1]):
                next_value = series.iloc[i + 1]
            else:
                next_value = series.iloc[i - 1]
            series.iloc[i] = (series.iloc[i - 1] + next_value) / 2
    return series

# データ作成
s = pd.Series([1, np.nan, 3, 4, np.nan, 6])

# カスタム関数で欠損値を補完
s_custom = my_backfill(s.copy())

print(s_custom)

利点

  • 完全な制御が可能

欠点

  • コード作成の手間がかかる

状況に応じて最適な方法を選択することが重要です。

  • より複雑な補間が必要な場合は、interpolate またはカスタム関数を使用します。
  • 単純な欠損値補完には fillna または backfill が適しています。