2016-11-23 3 views
1

Ich habe einen Pandas Datenrahmen nach der Form im Beispiel unten:Erstellen von Pivot Datenrahmen mit mehreren Spalten in Pandas

data = {'id': [1,1,1,1,2,2,2,2,3,3,3], 'a': [-1,1,1,0,0,0,-1,1,-1,0,0], 'b': [1,0,0,-1,0,1,1,-1,-1,1,0]} 
df = pd.DataFrame(data) 

Nun, was ich tun möchte, ist eine Pivot-Tabelle, dass eine solche erstellen für jede der Säulen außer der ID, werde ich 3 neue Spalten haben, die den Werten entsprechen. Das heißt, für die Spalte a erstelle ich a_neg, a_zero und a_pos. Ähnlich, für b, erstelle ich b_neg, b_zero und b_pos. Die Werte für diese neuen Spalten entsprechen der Häufigkeit, mit der diese Werte in der ursprünglichen Spalte a und b erscheinen.

result = {'id': [1,2,3], 'a_neg': [1, 1, 1], 
     'a_zero': [1, 2, 2], 'a_pos': [2, 1, 0], 
     'b_neg': [1, 1, 1], 'b_zero': [2,1,1], 'b_pos': [1,2,1]} 
df_result = pd.DataFrame(result) 

Nun, dies zu tun, kann ich die folgenden Schritte tun und auf meine endgültige Antwort kommen: Die letzte Datenrahmen sollte wie folgt aussehen

by_a = df.groupby(['id', 'a']).count().reset_index().pivot('id', 'a', 'b').fillna(0).astype(int) 
by_a.columns = ['a_neg', 'a_zero', 'a_pos'] 

by_b = df.groupby(['id', 'b']).count().reset_index().pivot('id', 'b', 'a').fillna(0).astype(int) 
by_b.columns = ['b_neg', 'b_zero', 'b_pos'] 

df_result = by_a.join(by_b).reset_index() 

Ich glaube jedoch, dass diese Methode nicht optimal vor allem, wenn ich neben a und b viele Originalsäulen habe. Gibt es eine kürzere und/oder effizientere Lösung, um das zu erreichen, was ich hier erreichen möchte? Vielen Dank.

Antwort

0

Eine kürzere Lösung, aber immer noch ganz in effizient:

In [11]: df1 = df.set_index("id") 

In [12]: g = df1.groupby(level=0) 

In [13]: g.apply(lambda x: x.apply(lambda x: x.value_counts())).fillna(0).astype(int).unstack(1) 
Out[13]: 
    a  b 
    -1 0 1 -1 0 1 
id 
1 1 1 2 1 2 1 
2 1 2 1 1 1 2 
3 1 2 0 1 1 1 

Anmerkung: Ich denke, Sie sollten für die Multi-Index-Spalten sein Ziel.


Ich bin ziemlich sicher, ich habe einen Trick gesehen die Anwendung/value_count/fillna mit etwas sauberen und effizienten, aber im Moment ist es entzieht sich mich zu entfernen ...

Verwandte Themen