私は項目(列)のカウントにマッピングするユーザー(インデックス)を保持する大規模なデータフレームがあります。ユーザーごとにカスタムグループを含むパンダの計算をベクトル化する方法は?
users_items = pd.DataFrame(np.array([[0, 1, 1, 0], # user 0
[1, 0, 0, 0], # user 1
[5, 0, 0, 9], # user 2
[0, 3, 5, 0], # user 3
[0, 2, 2, 0], # user 4
[7, 0, 0, 1], # user 5
[3, 5, 0, 4]]), # user 6
columns=list('ABCD'))
を、私は、少なくとも同じのための非ゼロカウントを持つすべてのユーザーを見つけたいですその数を合計します。したがって、ユーザー1の場合、これはユーザー1,2,5および6であり、カウントの合計は[16, 5, 0, 14]
になります。これは、 "類似した"ユーザーが持っているアイテムに基づいて、新しいアイテムをユーザーに提案するために使用できます。
このナイーブな実装では、すべての署名をループするループのための関連する行およびフィルタリングする正規表現として署名を使用する:
def create_signature(request_counts):
return ''.join('x' if count else '.' for count in request_counts)
users_items['signature'] = users_items.apply(create_signature, axis=1).astype('category')
current_items = users_items.groupby('signature').sum()
similar_items = pd.DataFrame(index=current_items.index,
columns=current_items.columns)
for signature in current_items.index:
row = current_items.filter(regex=signature, axis='index').sum()
similar_items.loc[signature] = row
結果は:
A B C D
signature
.xx. 0 6 8 0
x... 16 5 0 14
x..x 15 5 0 14
xx.x 3 5 0 4
この作品100kユーザーと約600項目からなる実際のデータセットでは遅すぎます。署名の生成にはわずか10秒しかかかりませんが、すべての署名(40k)の繰り返しには数時間かかります。
ループをベクトル化するとパフォーマンスは大幅に向上しますが、パンダの経験は限られているため、どうやったらいいか分かりません。このタイプの計算をベクトル化することも可能です。おそらくマスクを使用していますか?代わりに署名としてstring
の
で最後に
結果を、あなたのフィルターをvectoriseすることができます
.index
前
reset_index()
への呼び出しを挿入この例では4つの署名しかありませんか? .x ..、.xxx、x.xxなどの他の組み合わせが必要ですか?これらの4つはなぜ選ばれたのですか? – Allen@Allenシグネチャのセットは、users_itemsデータフレーム内にあるデータが何であっても単純に発生します。すべての可能な署名が発生するわけではありません。 –
'x ...'は、その署名のサブセットであるすべての行の合計である必要があります –