🐼

Pandasの欠損値処理

2021/09/05に公開

はじめに

Pandasで欠損値がある時に他の列の値を使って補完したい時があります。
今回はその手段に加えて、手段を思いつかずに回り道をしたパターンを
忘備録として掲載します。

サンプルパターン

次のデータフレームで、col2の欠損値をcol1の日付を3日足した値で埋める
ことを考えます。

import pandas as pd
import datetime

df = pd.DataFrame({'col1': ["2021/05/08", "2021/05/08", "2021/05/08"], 
'col2': ["2021/05/09", "2021/05/11", None]},
index=['row1', 'row2', 'row3'])

この時、各列は次のようにdatetime変換されているとします。

df["col1"] = pd.to_datetime(df["col1"])
df["col2"] = pd.to_datetime(df["col2"])

1:fillna

df["col2"].fillna(df["col1"]+ datetime.timedelta(days=3), inplace=True)

欠損値補完といったらfillnaになります。
これで解決なのですが、これが思いつきませんでした。

2:lambda関数

df["col2"] = df.apply(lambda x: x["col1"]+ datetime.timedelta(days=3)  if pd.isnull(x["col2"]) else x["col2"]  ,axis=1)

fillnaを思いつかずに私が取った方法になります。
lambda関数と三項演算子の組み合わせで補完しました。

3:mask関数

df["col2"].mask(pd.isnull(df["col2"]),df["col1"]+ datetime.timedelta(days=3), inplace=True)

2の後に思いついた方法になります。
lambda関数を書かなくてもこれですみます。

どうして回り道をしたのか

まず初めは別途defで関数を作成して補完しようとしたため、
apply関数を使った手段しか思いつかず、試行錯誤した結果が2番になります。
試行錯誤の結果、関数を作成する必要がなくなったので、
振り返ってみれば1番で解けたというオチです。

終わりに

今回の結果は徒労に終わりましたが、
例えば、col2列が欠損値ではなく、ある一定の値をとる場合に変更したい場合は
3番を使用すれば1行で変換できます。
また、複雑な処理をしたい場合は関数を作成する場合は2番が採用候補になります。
データをどう変換したいかはその時によって変わります。
その都度調べていたら時間の無駄だよね、ということでまとめました。
自分の忘備録として書きましたが、誰かの役に立てば幸いです。

Discussion