🐼

Pandasで飛び飛びのところを埋めるテクニック

2021/02/20に公開

今回は下記のような日付やID、数値データが組み合わされたpandasのDataFrameで、日付やIDが飛び飛びになっている場合に、飛んでいるところを埋めるテクニックをまとめたいと思います。

コードはこちら

このデータは 2020/1/1~1/8 におけるアイテムコード item_CD が A と B の2種類の売上です。

アイテムコード A は 1/2 や 1/4~1/6、アイテムコード B は 1/1、1/3、1/6~1/7 の売上がありません。

そのままグラフ化すると、売上がゼロのところが無視されてしまいます。

これを下記のように、売上がゼロのところもデータに含めるにはどうすればいいでしょうか?

date_range()

まず、date_range()を使って、全ての日付を含むデータを作成します。

template = pd.DataFrame(
    pd.date_range(start='2020/1/1', end='2020/1/8', freq='D'),
    columns=["date"]
)

http://ailaby.com/date_range/

さきほどのデータにアイテムコードの A、B のカラムを追加します。

中身は適当に 0 にしておきます。

template["A"] = 0
template["B"] = 0

melt()

melt()を使って、カラムに設定したアイテムコードの A と B を DataFrame の中に入れてやります。

数値部分はあとで消すので、適当に delete としておきます。

template = pd.melt(template, id_vars=df.columns.values[:1], var_name="item_CD", value_name="delete")

delete カラムは消しておきます。

これで全ての日付と、全ての アイテムコードを含むデータができました。

このデータと元々の売上を含むデータをマージすれば、売上がゼロの日付も含むデータができるわけです。

template = template[["date", "item_CD"]]

マージ用のカラム key の作成

ただ、日付やアイテムコードでマージしても重複してしまうので、日付とアイテムコードをつなげたマージ用のカラムを作成します。

df["key"] = df["date"].astype(str).str.cat(df["item_CD"], sep='-')
template["key"] = template["date"].astype(str).str.cat(template["item_CD"], sep='-')

]

https://note.nkmk.me/python-pandas-str-combine/

merge()

さきほど作成したマージ用のカラムで結合すれば、欲しいデータが出来上がります。

結合用のカラム以外に重複しているカラムがあると、カラム名_x、カラム名_y のようにカラム名が変わってしまうので、入っている値が同じならばあらかじめ除外しておきましょう。

今回の場合は、元々のデータの日付 date 、アイテムコード item_CD が重複しているので除外します。

df = pd.merge(template, df[["key", "price", "num", "sale"]], how="left", on="key")

売上ゼロの日付の売上がNaNになってしまっているので、fillna()で欠損値を0 で埋めてやります。

また、もうマージ用のカラム key も要らないので除外しましょう。

df = df.fillna(0)
df = df.drop("key", axis=1)

これでようやく売上がゼロの日付も含むデータができました。

冒頭と同じグラフですが、グラフ化するとちゃんと売上がゼロの日付も反映されました。

以上になります、最後までお読みいただきありがとうございました。

Discussion