2015-07-09 19 views
7

ich Pandas Datenrahmen mit zwei ID Variablen: closeUnmelt Pandas Dataframe

df.pivot('id','q','v') 

und am Ende mit etwas:

df = pd.DataFrame({'id': [1,1,1,2,2,3], 
       'num': [10,10,12,13,14,15], 
       'q': ['a', 'b', 'd', 'a', 'b', 'z'], 
       'v': [2,4,6,8,10,12]}) 

    id num q v 
0 1 10 a 2 
1 1 10 b 4 
2 1 12 d 6 
3 2 13 a 8 
4 2 14 b 10 
5 3 15 z 12 

ich die Tabelle mit schwenken kann

q a b d z 
id     
1 2 4 6 NaN 
2 8 10 NaN NaN 
3 NaN NaN NaN 12 

Was ich aber wirklich will ist (die ursprüngliche ungeschmolzene Form):

id num a b d z    
1 10 2 4 NaN NaN 
1 12 NaN NaN 6 NaN 
2 13 8 NaN NaN NaN 
2 14 NaN 10 NaN NaN 
3 15 NaN NaN NaN 12 

Mit anderen Worten:

  1. ‚id‘ und ‚num‘ meine Indizes (in der Regel habe ich nur entweder gesehen ‚id‘ oder ‚num‘ ist der Index aber ich brauche beide da ich m versuchen, das Original nicht geschmolzenen Form)
  2. 'q' sind meine Spalten
  3. meine Werte in der Tabelle sind

aktualisieren

'v' abrufen

Ich fand eine schließen Lösung von Wes McKinney's blog:

df.pivot_table(index=['id','num'], columns='q') 

     v    
q  a b d z 
id num     
1 10 2 4 NaN NaN 
    12 NaN NaN 6 NaN 
2 13 8 NaN NaN NaN 
    14 NaN 10 NaN NaN 
3 15 NaN NaN NaN 12 

jedoch das Format nicht ganz das gleiche wie das, was ich oben wollen.

Antwort

9

Sie sind ganz in der Nähe Slaw ‚q‘ fallen zu lassen. Benennen Sie einfach Ihren Spaltenindex in None um und Sie haben, was Sie wollen.

df2 = df.pivot_table(index=['id','num'], columns='q') 
df2.columns = df2.columns.droplevel().rename(None) 
df2.reset_index().fillna("null").to_csv("test.csv", sep="\t", index=None) 

Hinweis, dass das die ‚v‘ Spalte standardmäßig numerisch sein zu erwarten, so dass sie aggregiert werden können. Andernfalls wird die Fehler Pandas aus mit:

DataError: No numeric types to aggregate 

To resolve this, können Sie Ihre eigene Aggregationsfunktion angeben, indem Sie eine benutzerdefinierte Lambda-Funktion:

df2 = df.pivot_table(index=['id','num'], columns='q', aggfunc= lambda x: x) 
+0

Ahhh, ich war so nah! Ich wusste, dass es mit 'df.columns.name' zu ​​tun hatte, konnte aber nicht herausfinden, wie man' rename' richtig verwendet. Danke für Ihre Hilfe! – slaw

+1

Wichtiger Hinweis: "close slaw" klingt wie "Krautsalat". –

0

Kam mit einer engen Lösung bis

df2 = df.pivot_table(index=['id','num'], columns='q') 
df2.columns = df2.columns.droplevel() 
df2.reset_index().fillna("null").to_csv("test.csv", sep="\t", index=None) 

noch nicht herausfinden kann, wie aus dem Datenrahmen

5

Sie set_index verwenden könnte und unstack

In [18]: df.set_index(['id', 'num', 'q'])['v'].unstack().reset_index() 
Out[18]: 
q id num a  b d  z 
0 1 10 2.0 4.0 NaN NaN 
1 1 12 NaN NaN 6.0 NaN 
2 2 13 8.0 NaN NaN NaN 
3 2 14 NaN 10.0 NaN NaN 
4 3 15 NaN NaN NaN 12.0 
+0

So viel sauberer als die angenommene Antwort. Vielen Dank! – kev8484

+0

Vielen Dank. pandas.pivot() mit mehreren Indexspalten ist nicht so einfach wie ich gehofft hatte und diese Lösung hat stattdessen funktioniert. –

1

können Sie den Namen q entfernen.

df1.columns=df1.columns.tolist() 

Zeros Antwort + entfernen q =

df1 = df.set_index(['id', 'num', 'q'])['v'].unstack().reset_index() 
df1.columns=df1.columns.tolist() 

    id num a  b d  z 
0 1 10 2.0 4.0 NaN NaN 
1 1 12 NaN NaN 6.0 NaN 
2 2 13 8.0 NaN NaN NaN 
3 2 14 NaN 10.0 NaN NaN 
4 3 15 NaN NaN NaN 12.0