2016-08-24 39 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