pd.mergeで同じカラムがあるとcol_x, col_y...と別カラムが生える件
概要
pandasのmergeを繰り返し行うと意図せずcolumn_x
, column_y
...と、元々あったcolumn
に_x
, _y
とついてきて困ったことがある人向けです。
結果的に綺麗な解決策ではないですが、結合に使用するカラム名は揃えることは徹底した方が良さそうです。
どうしたの
pythonで機械学習の前準備をする際、特徴量生成のためにいくつかのcsvをマージすることはよくあると思います。
例えば、以下のようなデータがあったとします。
ds
が日付、y
がその日の値を表現します。
これにそれぞれ別のソースから獲得されるflag_1
とflag_2
というフラグを用意してmergeさせてみます(というケースを仮定します)。
データ生成コードはこちら。
feature_1 = pd.DataFrame({ "target_ds": df["ds"], "flag_1": np.random.binomial(1, 0.25, len(df)) }) feature_2 = pd.DataFrame({ "target_ds": df["ds"], "flag_2": np.random.binomial(1, 0.1, len(df)) }) flag_df_list = [feature_1, feature_2] })
これをいざマージして中身を見てみると、元々あったtarget_ds
というカラムがなくなり、代わりにtarget_ds_x
とtarget_ds_y
の、意図しないカラムが作られてしまっています。
for _df_flag in flag_df_list: df = pd.merge( left=df, right=_df_flag, how="left", left_on="ds", right_on="target_ds" ) df.head()
すでにds
というカラムがあるので、
どうするの
mergeするkeyとなるカラムの名称を全て揃えておけば問題なさそう。
以下のように、feature_1などの日付カラム名もds
に統一したところうまくいった。
feature_1 = pd.DataFrame({ "ds": df["ds"], "flag_1": np.random.binomial(1, 0.25, len(df)) }) feature_2 = pd.DataFrame({ "ds": df["ds"], "flag_2": np.random.binomial(1, 0.1, len(df)) }) flag_df_list = [feature_1, feature_2] for _df_flag in flag_df_list: df = pd.merge( left=df, right=_df_flag, how="left", ) df.head()
pd.merge
する時にleft_on
とright_on
の両方を使おうとした際は気をつけた方が良さそうです。
業務で詰まったポイントを再現するためこんな話の展開になっているけど、まあ普通に考えてfeature_1のカラム名をわざわざtarget_ds
にするなんて有り得ないよなというself-ツッコミで終わり。
参考
(一応コード) github.com