実現したいこと
- 以下の左図のように、グループ(group)に属する人物(person)のリストがあります。
- 各グループ内の人物が重複する人数をカウントし、右図のようにまとめたいと思っています。
- AとBは「2」がどちらにも含まれているので、重複している人物が1人 → freq = 1
- AとDは「2」「3」がどちらにも含まれているので、重複している人物が2人 → freq = 2
- グループは約3,000、人物はのべ5万人あるデータを処理します。
試してみたこと
- グループの組み合わせを作成。
- グループの組み合わせを参照しながら、該当するグループの重複を数える方法がないかと悩んでします。
python
1import pandas as pd 2import itertools 3 4data = pd.read_table("C:/Users/lisaco/data_0131.txt", encoding="utf-8") 5dt = data[['group', 'person']] 6 7u = dt['group'].unique() 8comb = itertools.combinations(u,2) 9 10name = ["group1", "group2"] 11dtx = pd.DataFrame(comb, columns=name) 12 13~~def func(x): 14 df.groupby('comb')['b'].agg(lambda x: list(x)):~~ 15 16~~df['freq'] = df.apply(func, axis=1)~~
よろしくお願いします。
どういう集計をする必要があるのか詳しく説明しよう
解決済みなので、コメントで。
もし、速度を求めるなら、group × person の 0, 1 テーブルを作って、行列積をとるのが簡単ですよ。

「丸投げ」と言われ、これが噂に聞いているアレかと思いました。たぶんもう投稿しません。
以前は、この素人が作ったロジックを提示したこともありましたが、どうにもならない意味不明さだったのでしょう、回答ゼロでした。
シンプルにやりたいことだけ書いたほうが良いのかもしれないとか、詰まっているポイントが言葉にならないから質問しないほうがいいのかもしれないとか、悩みながら質問しました。
私のような素人は、調べるのに相応しい単語、説明するのに適した単語さえ持っていないことが多いです。
教えていただいて、調べるキッカケを頂き、pythonの考え方に気づけたので、一気に理解が進みました。
melianさんには心から感謝致します。

bsdfanさん、ありがとうございます。
行列積、調べてみます。
余談になりますが、Numpy による行列積(numpy.matmul)は int 型のデータ(numpy.ndarray)で実行すると BLAS を利用しませんのでご注意下さい。以下に挙げる回答では numpy.dot を取り上げていますが、numpy.matmul でも同様です。
https://stackoverflow.com/a/19839985
実際に、手元の環境でグループ数 3,000, 人物 50,000 で実行すると 10 分以上経過しても終わらず、dtype を numpy.float32 に変更してから実行すると1.2秒で終了します。ただ、行列積を実行するためのテーブルの作成に多少の時間が掛かりますので、回答した方法の 2 倍程度の高速化になっています。
@melianさん
ご指摘の通り、巨大な整数の行列での積は遅くなるんでした。今回のケースとかだとscipy.sparseを使うのが良いのかもしれない気がしてきました。
どれぐらい疎かによりますが、2倍よりは速くなるのでは。

melianさん、bsdfanさん、ありがとうございます。
お二人の会話が高度で理解が追いつきませんが、研究させていただきます!
勉強になりました。ありがとうございます。

回答3件
あなたの回答
tips
プレビュー