2016-09-02 10 views
1

ここには、私が後にしていることのtl; dr版があります。詳細は下にあります: SQLクエリでは、[person 1 id]、[person 2 id]、[group in group]のフィールドを持つテーブルが表示されます。私は正方形のパンダのデータフレームに変換したいと思っています.1人1列と1人1列、各要素の値は一緒にグループに入っていた回数です。私は、私の結果の行を見て、一度にデータフレームの1つの要素を埋めるよりも、それを行うよりエレガントな方法を探しています。自己結合からスクエアパンダデータフレームへのSQL結果の変換


私はperson_idの列とassignment_idの列を持つ代入テーブルを持つデータベースを持っています。それはあまりにも他のものを持っているが、ここで我々の目的のために、これは重要なものである:

SELECT person_id, assignment_id FROM assignments; 
 
person_id | assignment_id 
----------+-------------- 
     385 |   42 
     163 |   29 
     51 |   42 
     385 |   37 
     163 |   37 
     ... 

私は二人が同じ割り当てにされている頻度を見てみたいです。だから私は実行します。

のような出力を提供します
SELECT a1.person_id AS p1_id, a2.person_id AS p2_id, COUNT(*) 
FROM assignments AS a1 
INNER JOIN assignments AS a2 ON a1.assignment_id = a2.assignment_id AND a1.person_id < a2.person_id 
GROUP BY a1.person_id, a2.person_id 

 
p1_id | p2_id | count 
------+-------+------ 
    51 | 385 | 1 
    163 | 385 | 1 
     ... 

は今、私は一人一人のために行とデータフレームにデータにアクセスし、それをダンプしたいPythonスクリプトを構築しています、各個人の列と、割り当てを共有した回数を持つセルとを含む。出力はこのようなものになります(私は*セルに何が入っているかは気にしません - 合理的に0またはその人の割り当ての数になる可能性があります)、最初の行と列がどのように)にフォーマット:

 
p1_id | p_51 | p_163 | p_385 
-------+--------+--------+-------- 
    51 | * | 0 | 1 
    163 | 0 | * | 1 
    385 | 1 | 1 | * 

私は約20人を持っていますので、ちょうど一つずつ値を設定することが測定可能パフォーマンスを傷つけないだろうが、私は私の方が大きい持っているときのために良い習慣を学ぶためにしようとしていますデータセット。このようなことをする正しい方法は何ですか?

(それはそれを処理するための最良の方法だ場合、私は、SQLクエリを変更するに開いている。)

答えて

1

あなたはそれらに参加するだけでなく、取ることによって、strと集計を入力するために必要な列を変換した後groupbyを使用することができます彼らのカウント。

df1 = pd.get_dummies(df['p_id_1']).add_prefix('p_') 
print (df1) 

     p_163 p_385 
p_id_0    
51  0.0 1.0 
163  0.0 0.0 
385  1.0 0.0 

df2 = pd.get_dummies(df['p_id_0']).add_prefix('p_') 
print (df2) 

     p_163 p_385 p_51 
p_id_0      
51  0.0 0.0 1.0 
163  1.0 0.0 0.0 
385  0.0 1.0 0.0 

そして、0にインデックス付きのフレームの全ての値をマッピングした後、これらの個々のdataframesを連結:示されるようにあなたがp_id_0、インデックスのインジケータ変数を取得するためにget_dummiesを使用することによってさらに簡素化することができ

df[['person_id', 'assignment_id']] = df[['person_id', 'assignment_id']].astype(str) 

df = df.groupby(['assignment_id'], as_index=False, sort=False)['person_id'] \ 
     .agg({'col':','.join})['col']           \ 
     .str.split(',').apply(lambda x: sorted(x, reverse=True))    \ 
     .apply(pd.Series).add_prefix('p_id_')         \ 
     .set_index('p_id_0', drop=False) 

同じ名前の列をまとめてグループ化します。

df_final = pd.concat([df1, df2.applymap(lambda x: 0)], axis=1).add_prefix('p_') 
print (df_final.groupby(df.columns, axis=1).sum()) 

     p_163 p_385 p_51 
p_id_0      
51  0.0 1.0 0.0 
163  0.0 0.0 0.0 
385  1.0 0.0 0.0 
+1

優れています。ありがとう! –