2016-08-24 3 views
3

ein eindeutiges Feld teilen Imagine ich einen Datenrahmen, die die Bücher speichert, die einzelne Menschen gelesen haben und für sie ihre Ergebnisse:Wie Zeilen zählen, die in Pandas

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 

Was ich will ist ein Datenrahmen zeigt bekommen für jedes Paar Bücher, wie viele Menschen sie haben, lesen sich wie das beide, dh das gewünschte Ergebnis aussieht:

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

Ie Es gibt zwei Leute, die sowohl dracula als auch frankenstein gelesen haben, eine Person, die sowohl dracula als auch rebecca gelesen hat usw. Ich interessiere mich nicht für die Punkte.

Ich habe das Gefühl, das hat etwas mit pivot/stack/unstack zu tun, aber kann es nicht herausfinden, irgendwelche Vorschläge?

Antwort

2

Eine andere Lösung mit 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 

Oder Lösung mit groupby und unstack:

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

Fantastische Danke für die beiden Lösungen - ich fin d die 'groupby' ist vertrauter, aber offensichtlich ist das genau die Art von Problem, für das' crosstab' gedacht ist, also werde ich mich bemühen, es zu lernen. – mojones

+0

Danke für die Annahme! Schöner Tag! – jezrael

3

Sie können eine Pivot-Tabelle erstellen und multiplizieren sie mit ihrer transponieren:

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