2016-04-08 6 views
1

Ich habe folgende Pivot-Tabelle, die ein Multi-Index ist, sowohl für die Indizes und die Spalte:Python Pandas Pivot-Tabelle - Hinzufügen von berechneten Spalt zu Multi-Index-Spalte

Category  HF      DA  
       tafp tap  tw  tafp tap  tafp 
ATTR EL      
attr1 1.0  10  25  15  100  150  50 
attr2 2.0  0  0  0  40  70  30 
     3.0  20  50  30  0  0  0 
attr3 2.0  0  0  0  0  0  0 

hier ein dict von diesem Pivot-Tabelle (Werte sind ein bisschen anders, aber das spielt keine Rolle):

{ 
('HF', 'tafp'): {('attr1', '1.0'): 10, ('attr2', '2.0'): 100, ('attr3','2.0'): 0, ('attr4', '2.0'): 0, ('attr2', '3.0'): 71}, 
('HF', 'tap'): {('attr1', '1.0'): 30, ('attr2', '2.0'): 350, ('attr3', '2.0'): 0, ('attr4', '2.0'): 0, ('attr2', '3.0'): 1042}, 
('HF', 'tw'): {('attr1', '1.0'): 20, ('attr2', '2.0'): 250, ('attr3', '2.0'): 0, ('attr4', '2.0'): 0, ('attr2', '3.0'): 971}, 
('DA', 'tafp'): {('attr1', '1.0'): 0, ('attr2', '2.0'): 435, ('attr3', '2.0'): 0, ('attr4', '2.0'): 0, ('attr2', '3.0'): 0}, 
('DA', 'tap'): {('attr1', '1.0'): 0, ('attr2', '2.0'): 635, ('attr3', '2.0'): 0, ('attr4', '2.0'): 0, ('attr2', '3.0'): 0}, 
('DA', 'tw'): {('attr1', '1.0'): 0, ('attr2', '2.0'): 200, ('attr3', '2.0'): 0, ('attr4', '2.0'): 0, ('attr2', '3.0'): 0} 
} 

Was ich am Ende bekommen wollen, ist die folgende:

Category  HF      DA  
       tafp/tap tw  tafp/tap tafp 
ATTR EL      
attr1 1.0  0.67  15  0.67  50 
attr2 2.0  0   0  0.57  30 
     3.0  0.67  30  0   0 
attr3 2.0  0   0  0   0 

Also würde ich gerne den Prozentsatz von tafp/tap bekommen und nur diese berechnete Spalte behalten, d. H. Die ursprünglichen Spalten löschen.

Hat jemand eine Idee, wie ich das erreichen kann?

Jede Hilfe wird sehr geschätzt :)

Antwort

2

In einigen Schritten.

Erste Stack-Ebene 0 ('DA,HF') Level 1 ('tafp','tap') als Spalten für die einfachere Handhabung.

df=df.stack(level=0) 
""" 
       tafp tap tw 
attr1 1.0 DA  0  0 0 
      HF 10 30 20 
attr2 2.0 DA 435 635 200 
      HF 100 350 250 
     3.0 DA  0  0 0 
      HF 71 1042 971 
attr3 2.0 DA  0  0 0 
      HF  0  0 0 
attr4 2.0 DA  0  0 0 
      HF  0  0 0 
""" 

Dann schreitet die Operation:

valid=df.tap>0 
df.tafp[valid] /= df.tap[valid] 

Schließlich wird die Neuformatierung:

df=df.drop('tap',axis=1).unstack() 
df.reorder_levels([1,0],axis=1).sort_index(axis=1) 

für:

""" 
       DA    HF  
       tafp tw  tafp tw 
attr1 1.0 0.000000 0 0.333333 20 
attr2 2.0 0.685039 200 0.285714 250 
     3.0 0.000000 0 0.068138 971 
attr3 2.0 0.000000 0 0.000000 0 
attr4 2.0 0.000000 0 0.000000 0 
""" 
+0

Thank you very much! Klappt wunderbar. Könnten Sie die Verwendung des Arguments "level" im Stack und im Stack erklären? Ich verstehe, was es bedeutet, aber warum verwenden Sie level = 2 beim Entstapeln? –

+1

weil ('HF', 'DA') ist jetzt die dritte (Index 2) Spalte von Zeilen-Index, aber es ist der Standard, also entferne ich es. –