はじめに
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番が採用候補になります。
データをどう変換したいかはその時によって変わります。
その都度調べていたら時間の無駄だよね、ということでまとめました。
自分の忘備録として書きましたが、誰かの役に立てば幸いです。
#更新情報
2021.9.6 lambda関数の記述で
+ datetime.timedelta(days=3)
が抜けていたので追記