このような元データがあった際に
country | tag |
---|---|
日本 | 食事,温泉 |
フランス | 食事,ファッション,文化 |
オーストラリア | 自然 |
ニュージーランド | 自然 |
このようなデータをつくりたいときのやり方
country | 食事 | 温泉 | ファッション | 文化 | 自然 |
---|---|---|---|---|---|
日本 | 1 | 1 | 0 | 0 | 0 |
フランス | 1 | 0 | 1 | 1 | 0 |
オーストラリア | 0 | 0 | 0 | 0 | 1 |
ニュージーランド | 0 | 0 | 0 | 0 | 1 |
まずはこの↓元となるdfを
country | tag |
---|---|
日本 | 食事,温泉 |
フランス | 食事,ファッション,文化 |
オーストラリア | 自然 |
ニュージーランド | 自然 |
temp = df.tag.str.extractall('([^,]+)')
で、tag部分のみを抽出して以下のtempをつくる
0 | ||
---|---|---|
match | ||
0 | 0 | 食事 |
0 | 1 | 温泉 |
1 | 0 | 食事 |
1 | 1 | ファッション |
1 | 2 | 文化 |
2 | 0 | 自然 |
3 | 0 | 自然 |
不要なマルチインデクスのmatchを以下で削除して
temp = temp.reset_index(1, True)
0 | |
---|---|
0 | 食事 |
0 | 温泉 |
1 | 食事 |
1 | ファッション |
1 | 文化 |
2 | 自然 |
3 | 自然 |
をつくる。
さらにこのtempと最初のdfをマージして、tidyなdf3を作る
df3 = pd.merge(df,temp,left_index=True,right_index=True)
df3 = df3.drop("tag",axis=1)
df3 = df3.rename(columns={0:"tag_name"})
df3
df3はこんな感じ
index | country | tag_name |
---|---|---|
0 | 日本 | 食事 |
0 | 日本 | 温泉 |
1 | フランス | 食事 |
1 | フランス | ファッション |
1 | フランス | 文化 |
2 | オーストラリア | 自然 |
3 | ニュージーランド | 自然 |
このdf3のインデクスをcountryにする
df3 =df3.set_index("country")
こんな感じになる
country | tag_name |
---|---|
日本 | 食事 |
日本 | 温泉 |
フランス | 食事 |
フランス | ファッション |
フランス | 文化 |
オーストラリア | 自然 |
ニュージーランド | 自然 |
このdf3をone-hotコーディングしたdf_one_hotをつくる
df_one_hot = pd.get_dummies(df3["tag_name"])
df_one_hot = df_one_hot.reset_index()
df_one_hot
こんな感じのものができる
country | 食事 | 温泉 | ファッション | 文化 | 自然 | |
---|---|---|---|---|---|---|
0 | 日本 | 1 | 0 | 0 | 0 | 0 |
1 | 日本 | 0 | 1 | 0 | 0 | 0 |
2 | フランス | 1 | 0 | 0 | 0 | 0 |
3 | フランス | 0 | 0 | 1 | 0 | 0 |
4 | フランス | 0 | 0 | 0 | 1 | 0 |
5 | オーストラリア | 0 | 0 | 0 | 0 | 1 |
6 | ニュージーランド | 0 | 0 | 0 | 0 | 1 |
このdf_one_hotをcountryでgroupbyする
df_gby = df_one_hot.groupby("country").sum().reset_index()
df_gby
完成。
index | country | 食事 | 温泉 | ファッション | 文化 | 自然 |
---|---|---|---|---|---|---|
0 | 日本 | 1 | 1 | 0 | 0 | 0 |
1 | フランス | 1 | 0 | 1 | 1 | 0 |
2 | オーストラリア | 0 | 0 | 0 | 0 | 1 |
3 | ニュージーランド | 0 | 0 | 0 | 0 | 1 |
もっとうまいやり方がありそうだが、とりあえず知ってる知識でのやり方。