以下のようなデータを
user_id,item_id
A,1
A,1
A,2
A,12
B,1
B,4
以下のようなデータの形状に変換したい。
item_id_1 | item_id_2 | item_id_3 | item_id_4 | item_id_5 | item_id_6 | item_id_7 | item_id_8 | item_id_9 | item_id_10 | item_id_11 | item_id_12 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
A | 2 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
B | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
データとしては、item_id
の列に出てきた最大最小の値を両端として、その間の数値をカラム名として補完しながら、出現回数をカウントしたものである。
csvの読み込み
import pandas as pd
df = pd.read_csv("user_item.csv")
df_dummies = pd.get_dummies(df, columns=['item_id']).groupby(['user_id']).sum()
df_dummies
は以下のようになる
user_id | item_id_1 | item_id_2 | item_id_4 | item_id_12 |
---|---|---|---|---|
A | 2 | 1 | 0 | 1 |
B | 1 | 0 | 1 | 0 |
足りないカラムを補足する
前段のステップだと、item_idが1,2,4,12のものはできたが、その間のカラムができていない。そこでここで準備する。
# カラムの生成
columns = [f"item_id_{i}" for i in range(min(df["item_id"]), max(df["item_id"])+1)]
df_base = pd.DataFrame(columns = columns)
補足のカラムと元データを合わせる
補完したカラムをもつデータフレームと元のデータを合わせることで、目的のカラムを持つデータフレームが生成できる。ただ、補完したカラムのデータがNaN
になるため、0で書き換える。
df_target = pd.concat([df_base, df_dummies], sort=True).fillna(0)
さらに、これだとカラムの順番がバラバラなので順番を並び替える。
df_target = df_target[columns] # columnsにはhuman sortingの順序で入っている。
df_target
関数にしてみたもの
def complementedDummies(df, column_a, column_b):
df_dummies = pd.get_dummies(df, columns=[column_b]).groupby([column_a]).sum()
columns = [f"{column_b}_{i}" for i in range(min(df[column_b]), max(df[column_b])+1)]
df_base = pd.DataFrame(columns = columns)
df_target = pd.concat([df_base, df_dummies], sort=True).fillna(0)
return df_target[columns]
df_changed = complementedDummies(df_a, "user_id", "item_id")