df
id | like | |
---|---|---|
0 | 1 | 2 |
1 | 1 | 4 |
2 | 12 | 6 |
3 | 12 | 7 |
4 | 12 | 8 |
.. | ||
19998 | 19912 | 200 |
19999 | 1441 | 90 |
20000 | 1441 | 91 |
変更後
||id|1|2|3|4|5|6|7|8|...|90|91|...|200|
|:--|:--:|--:|
|0|1|0|1|0|1|0|0|0|0|...|0|0|...|0|
|1|12|0|0|0|0|0|1|1|1|...|0|0|...|0|
|2|...|...|||||
|3|...|...|||||
|4|...|...|||||
|...|1441|0|0|0|0|0|0|0|0|...|1|1|...|0|
|...|...|...|||
|...|...|...|||
|1000|19912|0|0|0|0|0|0|0|0|...|0|0|...|1|
としたい(カラム名は適当)
likeカラムを.astype(str)した後
dummy = pd.get_dummies(df['like'])
pd.concat([df, dummy], axis=1)とする方法を考えたのですが、
その後df.groupby('id')を利用して統合したいのですがどうしたらよいかわかりません。
他の方法があればご教授いただきたいです。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答4件
0
ベストアンサー
データフレームの変形を考えるのではなく、
ゼロ配列を用意した後に、like
列をインデックスとして1を入れたほうが速いですね。
python
1import pandas as pd 2import io 3 4txt = """ 5id,like 61,2 71,4 812,6 912,7 1012,8 1119912,200 121441,90 131441,91 14""" 15df = pd.read_csv(io.StringIO(txt)) 16# id like 17# 0 1 2 18# 1 1 4 19# 2 12 6 20# 3 12 7 21# 4 12 8 22# 5 19912 200 23# 6 1441 90 24# 7 1441 91
このとき、
python
1import numpy as np 2 3code, unq = df['id'].factorize(sort=True) 4like = df['like'].to_numpy() 5arr = np.zeros((unq.size, like.max()+1), dtype=np.int8) 6arr[code, like] = 1 7out = pd.DataFrame(arr, index=unq) 8 9out 10# 0 1 2 3 4 5 6 7 8 9 10 ... 190 191 192 193 194 195 196 197 198 199 200 11# 1 0 0 1 0 1 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0 0 12# 12 0 0 0 0 0 0 1 1 1 0 0 ... 0 0 0 0 0 0 0 0 0 0 0 13# 1441 0 0 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0 0 14# 19912 0 0 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0 1
投稿2020/09/09 07:39
総合スコア1399
0
Python
1import pandas as pd 2import io 3 4txt = """ 5id,like 61,2 71,4 812,6 912,7 1012,8 1119912,200 121441,90 131441,91 14""" 15 16df = pd.read_table(io.StringIO(txt), sep=",") 17like_max = df['like'].max() 18s = df.groupby('id')['like'].apply(list) 19dic = {i: [int(j in s[i]) for j in range(1, like_max + 1)] for i in s.index} 20 21dfn = pd.DataFrame(dic).transpose() 22dfn.index.name = 'id' 23dfn.rename(columns=lambda x: x + 1, inplace=True) 24print(dfn)
result
1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ... 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 2id ... 31 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 412 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 51441 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 619912 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
投稿2020/09/09 02:42
総合スコア11990
0
ちょっと手順が複雑になってしまったので各行にコメントを入れてあります。
id列をインデックスとすることでid列を維持したままダミー変数を作成する方法です。
python
1import pandas as pd 2from io import StringIO 3 4s1 = '''id,like 51,2 61,4 712,6 812,7 912,8 1019912,200 111441,90 121441,91''' 13# id列をインデックスでDataframeを作成 14df = pd.read_csv(StringIO(s1), index_col=0) 15 16# 列作成のためlikeの最大値を取得する 17max_val = max(df['like']) 18 19df['like'] = df['like'].astype(str) 20# dummy変数作成 21dummy = pd.get_dummies(df['like']) 22# インデックス(id列)をグループで最大値を求める 23dummy = dummy.groupby(level=0).max() 24# id列をデータ列に戻す 25dummy = dummy.reset_index() 26 27# 列名がid、1~200まで持つダミーDataframeの作成 28adf = pd.DataFrame([[-1] + ['0' for i in range(1, max_val + 1)]], 29 columns=['id'] + [str(i) for i in range(1, max_val + 1)]) 30 31# ダミーDataframeを結果Dataframeを結合する 32df_concat = pd.concat([adf, dummy]) 33# 欠損地を'0'に変換 34df_concat = df_concat.fillna('0') 35# id列が-1(ダミー)の行を削除 36df_concat = df_concat[df_concat['id'] != -1] 37 38print(df_concat) 39''' 40 id 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ... 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 410 1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 421 12 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 432 1441 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 443 19912 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 45 46[4 rows x 201 columns] 47'''
投稿2020/09/09 02:14
編集2020/09/09 02:19総合スコア2183
0
groupbyのあと、maxで集計すればいいのではないでしょうか。
python
1pd.get_dummies(df['like']).groupby(df['id']).max()
他にはpivot, pivot_tableを使ったやり方もあると思います。
追記
カラムを連番で埋めたい場合は、最後にreindexすればいいです。
python
1import numpy as np 2 3pd.get_dummies(df['like']).groupby(df['id']).max().reindex(columns=np.arange(1, df['like'].max() + 1), fill_value=0)
投稿2020/09/09 02:03
編集2020/09/09 02:56総合スコア4794
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。