Pandasで飛び飛びのところを埋めるテクニック
今回は下記のような日付や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"]
)
さきほどのデータにアイテムコードの 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='-')
]
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