2016-05-12 7 views
0

Angesichts der folgenden Pivot-Tabelle:Pandas Alle ersetzen Aber Mittelwerte pro Kategorie einer Stufe mit Blank

df=pd.DataFrame({'A':['a','a','a','a','a','b','b','b','b'], 
       'B':['x','y','z','x','y','z','x','y','z'], 
       'C':['a','b','a','b','a','b','a','b','a'], 
       'D':[7,5,3,4,1,6,5,3,1]}) 
table = pd.pivot_table(df, index=['A', 'B','C'],aggfunc='sum') 
table 

      D 
A B C 
a x a 7 
     b 4 
    y a 1 
     b 5 
    z a 3 
b x a 5 
    y b 3 
    z a 1 
     b 6 

Ich weiß, dass ich die Werte eines jeden Levels like so zugreifen:

In [128]:  
table.index.get_level_values('B') 

Out[128]: 
Index(['x', 'x', 'y', 'y', 'z', 'x', 'y', 'z', 'z'], dtype='object', name='B') 

In [129]: 
table.index.get_level_values('A') 

Out[129]: 
Index(['a', 'a', 'a', 'a', 'a', 'b', 'b', 'b', 'b'], dtype='object', name='A') 

Weiter Ich möchte alle Werte in jeder der äußeren Ebenen durch Leerzeichen ('') ersetzen, die für die mittleren oder n/2 + 1 Werte gespeichert sind.

Damit:

Index(['x', 'x', 'y', 'y', 'z', 'x', 'y', 'z', 'z'], dtype='object', name='B') 

wird:

Index(['x', '', 'y', '', 'z', 'x', 'y', 'z', ''], dtype='object', name='B') 

und

Index(['a', 'a', 'a', 'a', 'a', 'b', 'b', 'b', 'b'], dtype='object', name='A') 

wird:

Index(['', '', 'a', '', '', '', 'b', '', ''], dtype='object', name='A') 

Letztlich werde ich versuchen, diese als sekundäre und tertiäre y-Achse Etiketten zu verwenden, in einer Matplotlib Reck, etwas Diagramm wie dieses (obwohl einige meiner Etiketten nach oben verschoben werden kann): enter image description here

Antwort

0

nahm schließlich die Zeit Finde dies heraus ...

#First, get the values of the index level. 
A=table.index.get_level_values(0) 

#Next, convert the values to a data frame. 
ndf = pd.DataFrame({'A2':A.values}) 

#Next, get the count of rows per group. 
ndf['A2Count']=ndf.groupby('A2')['A2'].transform(lambda x: x.count()) 

#Next, get the position based on the logic in the question. 
ndf['A2Pos']=ndf['A2Count'].apply(lambda x: x/2 if x%2==0 else (x+1)/2) 

#Next, order the rows per group. 
ndf['A2GpOrdr']=ndf.groupby('A2').cumcount()+1 

#And finally, create the column to use for plotting this level's axis label. 
ndf['A2New']=ndf.apply(lambda x: x['A2'] if x['A2GpOrdr']==x['A2Pos'] else "",axis=1) 
ndf 

    A2 A2Count A2Pos A2GpOrdr A2New 
0 a 5  3.0  1  
1 a 5  3.0  2  
2 a 5  3.0  3  a 
3 a 5  3.0  4  
4 a 5  3.0  5  
5 b 4  2.0  1  
6 b 4  2.0  2  b 
7 b 4  2.0  3  
8 b 4  2.0  4