2016-08-24 44 views
3

想象我有一個存儲了個別人看過的書和他們的得分爲他們數據幀:如何計算,在大熊貓共用一個唯一的字段行

df = pd.DataFrame({ 
'person' : [1,1,2,2,3,3], 
'book' : ['dracula', 'frankenstein', 'dracula', 'frankenstein', 'dracula', 'rebecca'], 
'score':[10,11,12,13,14,15] 
}) 

df 

      book person score 
0  dracula  1  10 
1 frankenstein  1  11 
2  dracula  2  12 
3 frankenstein  2  13 
4  dracula  3  14 
5  rebecca  3  15 

我想要得到的是一個數據幀的表現對於每一本書有多少人已經讀過它們兩個,即期望的結果如下所示:

   dracula frankensten rebecca 
dracula   3    2   1 
frankenstein  2    2   0 
rebecca   1    0   1 

Ie有兩個人同時閱讀了dracula和,一個人同時閱讀了dracularebecca等。我不在乎分數。

我有一種感覺,這與樞軸/堆棧/斯塔克有關,但無法弄清楚,有什麼建議嗎?

回答

2

crosstab另一種解決方案:

df = pd.crosstab(df.book, df.person) 
print (df.dot(df.T)) 
book   dracula frankenstein rebecca 
book           
dracula    3    2  1 
frankenstein  2    2  0 
rebecca    1    0  1 

或解決方案與groupbyunstack

df = df.groupby(['book','person'])['person'].size().unstack().fillna(0).astype(int) 
print (df.dot(df.T)) 
book   dracula frankenstein rebecca 
book           
dracula    3    2  1 
frankenstein  2    2  0 
rebecca    1    0  1 
+0

神奇,謝謝你提供了兩個解決方案 - 我鰭d'groupby'更加熟悉,但很顯然,這正是'crosstab'用於解決問題的類型,所以我會努力學習它。 – mojones

+0

謝謝你的接受!美好的一天! – jezrael

3

您可以構建一個數據透視表,並與它的轉置相乘:

pvt = pd.pivot_table(df, index='book', columns='person', aggfunc=len, fill_value=0) 
pvt.dot(pvt.T) 
Out: 
book   dracula frankenstein rebecca 
book           
dracula    3    2  1 
frankenstein  2    2  0 
rebecca    1    0  1