API · Pandas

Pandas DataFrame DataFrame.interpolate() 関数

DataFrame interpolate()関数は、DataFrame 内の NaN 値を補間技術を用いて埋めます。

このページの内容

Python Pandas の DataFrame.interpolate() は、選択した軸に沿って周囲の値から欠損値を推定します。前後に利用できる値がある場合は、その間の欠損を補えますが、データに十分な情報がなければ欠損値が残ることがあります(NaN)。

pandas.DataFrame.interpolate() の構文とパラメーター

メソッド呼び出しの一般的な形式は次のとおりです。

DataFrame.interpolate(method="linear", axis=0, limit=None, inplace=False, limit_direction="forward", limit_area=None, **kwargs)

例では小さな数値の DataFrame を使っています。入力を自分のデータに合わせて変更してください。

パラメーター 制御する内容
method 補間方法です。この記事では既定の linear と time を扱います。インストール済みのバージョンで利用できる選択肢は、pandas の API ドキュメントで確認してください。
axis 補間する方向です。0 は各列の中で行方向に処理し、1 は各行の中で列方向に処理します。
limit 1つの欠損区間で補う、連続した欠損値の最大数です。
limit_direction limit を指定した場合に、欠損区間の先頭("forward")、末尾("backward")、または両端("both")のどちらから補うかを選びます。
inplace True の場合、元の DataFrame を変更します。既定値は False です。
limit_area limit を設定した場合に、値を補う場所を制限するオプションです。この記事の例では使用しません。
**kwargs 選択した補間方法が受け付ける追加のキーワード引数です。意味は補間方法によって異なります。

既定の方法で欠損値を補間する

既定の method="linear" では、選択した軸上の位置が等間隔であるものとして値を推定します。例では、10 と 30 の間の値は 20 と推定されます。また、末尾の欠損値には直前の既知の値が引き継がれ、30.0 になります。

次の例を実行します。

import pandas as pd

df = pd.DataFrame({"temperature": [10.0, None, 30.0, None]})
result = df.interpolate()
print(result)
   temperature
0         10.0
1         20.0
2         30.0
3         30.0

例に含まれる表示ラベルは、変更されていないため英語のままです。補間は、周囲の観測値から欠損値を推定したい場合に使います。pandas.DataFrame.fillna() は、指定した値や別の方法で欠損値を置き換えます。どちらが適切かは、データと目的によって異なります。

補間方法を選ぶ

行の位置が等間隔である通常の数値データでは、既定の method を使います。時刻をインデックスに持つ DataFrame では、method="time" によってインデックスが表す時間間隔を使って値を推定できます。観測時刻が等間隔でない場合に便利です。時刻に基づく例では、必要なインデックスの形式を示しています。

利用できる方法やその要件は、pandas のバージョンによって異なる場合があります。別の方法を選ぶ場合や、方法固有のキーワード引数を渡す場合は、使用するバージョンの API ドキュメントを確認してください。

補間する軸を選ぶ

既定の axis=0 は各列を下方向に補間します。axis=1 を指定すると、各行の中で列を横方向に補間します。たとえば axis=1 では、1行の中にある 10 と 30 の間の欠損値は 20 と推定されます。行に既知の値が1つもなければ、推定に使える値がないため、その行の値は欠損したままです。

import pandas as pd

df = pd.DataFrame(
    {"morning": [10.0, None], "afternoon": [None, None], "evening": [30.0, None]},
    dtype="float64",
)
print(df.interpolate(axis=1))
   morning  afternoon  evening
0     10.0       20.0     30.0
1      NaN        NaN      NaN

数値型を明示すると、すべて欠損している列も数値型のままになるため、行方向の補間が機能します。この axis=1 の例では、列名ではなく列の位置によって線形補間の間隔が決まります。

連続する欠損値の数を制限し、補う方向を指定する

limit を設定すると、pandas が各欠損区間で補う連続欠損値の数を制限できます。limit_direction は、その上限を適用する方向を制御します。0 と 40 の間に欠損値が3つある場合、limit=1 と前方向の補間を指定すると、上から最初の欠損位置が補われます。後方向の補間では、下から最後の欠損位置が補われます。それ以外の欠損位置は欠損のままです。

import pandas as pd

df = pd.DataFrame({"reading": [0.0, None, None, None, 40.0]})
print("Forward:")
print(df.interpolate(limit=1, limit_direction="forward"))
print("Backward:")
print(df.interpolate(limit=1, limit_direction="backward"))
Forward:
   reading
0      0.0
1     10.0
2      NaN
3      NaN
4     40.0
Backward:
   reading
0      0.0
1      NaN
2      NaN
3     30.0
4     40.0

両端から補うのが適切な場合は limit_direction="both" を使います。欠損区間が limit より長いときは、補間後のデータを確認してください。

時刻をインデックスに持つデータを補間する

時刻による補間では、日付と経過時間を通常の列にある文字列ではなく、インデックス値として扱える DatetimeIndex を使います。1月2日は1月1日から1月4日までの間隔の3分の1にあたります。そのため、補間値も10から30までの3分の1の位置となり、16.666667 になります。

import pandas as pd

index = pd.to_datetime(["2024-01-01", "2024-01-02", "2024-01-04"])
df = pd.DataFrame({"value": [10.0, None, 30.0]}, index=index)
print(df.interpolate(method="time"))
                value
2024-01-01  10.000000
2024-01-02  16.666667
2024-01-04  30.000000

時刻による補間では、日時インデックスを維持してください。日付を通常のテキスト列に変換すると、この方法で使われる時間間隔が得られません。

戻り値と inplace の動作

既定では、DataFrame.interpolate() は補間結果を含む新しい DataFrame を返し、元のオブジェクトは変更しません。inplace=True の場合は元の DataFrame を変更して None を返すため、結果を変数に代入するのは既定の動作を使う場合だけです。

import pandas as pd

df = pd.DataFrame({"reading": [1.0, None, 3.0]})
result = df.interpolate(inplace=True)
print(result)
print(df)
   reading
0      1.0
1      2.0
2      3.0
   reading
0      1.0
1      2.0
2      3.0

最初に表示される値は None で、2つ目は変更後の DataFrame です。