2017-03-16 8 views
2

Ich habe eine Tabelle wie folgt:Python Pandas: Pivot-Tabelle

Name | ID | Contact_method | Contact 
sarah 1 house   h1 
sarah 1 mobile   m1 
sarah 1 email   [email protected] 
bob  2 house   h2 
bob  2 mobile   m2 
bob  2 email   [email protected] 
jones 3 house   h3 
jones 3 mobile   m3 
jones 3 email   [email protected] 
jones 4 house   h4 
jones 4 mobile   m4 
jones 4 email   [email protected] 

Und ich will es wie so:

Name | ID | house | mobile | email 
sarah 1 h1  m1  [email protected] 
bob  2 h2  m2  [email protected] 
jones 3 h3  m3  [email protected] 
jones 4 h4  m4  [email protected] 

Ich kann dies bereits tun, sondern nur durch einen sehr teueren pd.concat Betrieb über alle eindeutigen IDs iteriert. Gibt es einen einfachen Weg, dies zu tun? Ich habe auch mit pivot() und transpose() gebastelt. Beachten Sie, dass der doppelte Name vorhanden ist, so dass ich mich nicht auf die Eindeutigkeit von Spaltenwerten verlassen kann, z. B. eine join.

Antwort

2

den Index mit allen Spalten außer 'Contact_method' Set, dann unstack

df.set_index(
    ['Name', 'ID', 'Contact_method'] 
)['Contact'].unstack().rename_axis(None, 1).reset_index() 

    Name ID  email house mobile 
0 bob 2  [email protected] h2  m2 
1 jones 3 [email protected] h3  m3 
2 jones 4 [email protected] h4  m4 
3 sarah 1 [email protected] h1  m1 
+0

Ich habe einen Schreibtisch an in meinem neuen temporären Platz zu sitzen, während wir schauen weiter für Häuser. Ich bin vorerst auf Fernarbeit eingestellt. Ich werde zweimal im Monat zurück nach Seattle pendeln. Und bald muss ich zurückgehen, um meine alten Sachen loszuwerden. Immer noch beschäftigt, aber ich habe es genossen, etwas Zeit zu haben, um Fragen zu beantworten. Ich hoffe, es geht dir gut! @jezrael – piRSquared

+0

@jezrael Ja, ich machte einen großen Push für legendär, dann fühlte ich, dass ich mich etwas beruhigen konnte. Du bist fast immer Top Pandas. Mein nächstes SO-Ziel wird es sein, an DSM und Jeff vorbeizukommen. Ich war noch nie sehr motiviert von Rep selbst. Ich habe viel weggegeben. Ich bekomme schließlich 100k .. Ich will ein T-Shirt. Du musst mich wissen lassen, wenn sie dir etwas geben. – piRSquared

+0

Ich möchte an http://stats.stackexchange.com/ und http://quant.stackexchange.com/ teilnehmen. Allerdings würde ich mir lieber ein paar andere Tags aussuchen, um Gold zu bekommen. Ich möchte mein nummeriertes Abzeichen, ich habe meine maschinellen Lerninhalte vernachlässigt. Ich möchte ein Gold-Abzeichen im Tensorflow bekommen (obwohl ich noch eine Menge zu lernen habe) – piRSquared

0

Eine Möglichkeit besteht darin, ein Kontaktwörterbuch (von Wörterbüchern) basierend auf der ID 'manualy' zu erstellen. Nicht sicher, ob es effizienter ist.

people = dict() 
for index, row in pd.iterrows(): 
    ID = row['ID'] 
    if ID not in people: 
     people[ID] = {'ID': ID, 'Name': row['Name']} 
    people[ID][row['Contact_method']] = row['Contact'] 

print pandas.DataFrame(people).transpose() 

Und Ausgabe lautet:

ID Name  email house mobile 
1 1 sarah [email protected] h1  m1 
2 2 bob  [email protected] h2  m2 
3 3 jones [email protected] h3  m3 
4 4 jones [email protected] h4  m4 
0

Oder können Sie schwenken verwenden:

df1.set_index(['ID','Name']).pivot(columns='Contact_method').reset_index() 
0

I denke piRSquared's solution ist sehr schön, aber wenn bekommen:

ValueError: Index contains duplicate entries, cannot reshape

print (df) 
    Name ID Contact_method  Contact 
0 sarah 1   house   h1 
1 sarah 1   mobile   m1 
2 sarah 1   email [email protected] 
3  bob 2   house   h2 
4  bob 2   mobile   m2 
5  bob 2   email  [email protected] 
6 jones 3   house   h3 
7 jones 3   mobile   m3 
8 jones 3   email [email protected] <-for same Name,ID and Contact_method get duplicate 
9 jones 3   email  [email protected] <-for same Name,ID and Contact_method get duplicate 
10 jones 4   house   h4 
11 jones 4   mobile   m4 
12 jones 4   email [email protected] 

Verwendung pivot_table oder groubpy mit Aggregieren join:

cols = ['Name','ID','house','mobile','email'] 
df1 = df.pivot_table(index=['ID','Name'], 
        columns='Contact_method', 
        values='Contact', 
        aggfunc=','.join) 
     .rename_axis(None, 1) 
     .reset_index() 
     .reindex_axis(cols, axis=1) 
print (df1) 
    Name ID house mobile    email 
0 sarah 1 h1  m1   [email protected] 
1 bob 2 h2  m2    [email protected] 
2 jones 3 h3  m3 [email protected],[email protected] <- join duplicates 
3 jones 4 h4  m4   [email protected] 

df1 = df.groupby(['Name', 'ID', 'Contact_method'])['Contact'] 
     .apply(','.join) 
     .unstack() 
     .rename_axis(None, 1) 
     .reset_index() 
     .reindex_axis(cols, axis=1) 
print (df1) 
    Name ID house mobile    email 
0 sarah 1 h1  m1   [email protected] 
1 bob 2 h2  m2    [email protected] 
2 jones 3 h3  m3 [email protected],[email protected] <- join duplicates 
3 jones 4 h4  m4   [email protected]