2016-06-10 12 views
1

dieses Datenrahmen und Pivot-Tabelle Gegeben:Pandas Multiindex Nested Sortieren und Percent

import pandas as pd 
df=pd.DataFrame({'County':['A','A','A','A','A','B','B','B','B','A','A','A','A','A','B','B','B','B'], 
       'Hospital':['a','b','c','d','e','a','b','c','e','a','b','c','d','e','a','b','c','e'], 
       'Enrollment':[44,55,42,57,95,54,27,55,81,54,65,23,89,76,34,12,1,67], 
       'Year':['2012','2012','2012','2012','2012','2012','2012','2012','2012','2013', 
         '2013','2013','2013','2013','2013','2013','2013','2013']}) 
d2=pd.pivot_table(df,index='Year',columns=['County','Hospital']) 
d2 
      Enrollment 
County  A     B 
Hospital a b c d e a b c e 
Year          
2012  44 55 42 57 95 54 27 55 81 
2013  54 65 23 89 76 34 12 1 67 

Ich mag würde folgendes tun:

  1. Berechnen Sie die Prozent der Krankenhaus 'Enrollment' (pro Kreis) für das letzte Jahr, wie folgt aus:

      Enrollment        
    County  A     B   
    Hospital a b c d e a b c e 
    Year          
    2012  44 55 42 57 95 54 27 55 81 
    2013  54 65 23 89 76 34 12 1 67 
    Percent  18% 21% 7% 29% 25% 30% 11% 1% 59% 
    
  2. sortieren die Spalten von 'Enrollment' (desce ndingly) für das letzte Jahr, wie folgt aus:

      Enrollment        
    County  A     B   
    Hospital d e b a c e a b c 
    Year          
    2012  57 95 55 44 42 81 54 27 55 
    2013  89 76 65 54 23 67 34 12 1 
    Percent  29% 25% 21% 18% 7% 59% 30% 11% 1% 
    
  3. Nehmen Sie die Top-3 Krankenhäuser (in Bezug auf die Einschreibung für die letzten zwei Jahre) pro Kreis wie folgt aus:

      Enrollment     
    County  A   B  
    Hospital d e b e a b 
    Year       
    2012  57 95 55 81 54 27 
    2013  89 76 65 67 34 12 
    Percent  29% 25% 21% 59% 30% 11% 
    

Danke voraus!

P.S. Bisher habe ich versucht, durch Umsetzung zu sortieren und mit Landkreis und der rechten Spalte für das letzte Jahr:

cnty=d2.T.index.names[1] 
ryr=d2.T.columns[-1] 
d2.T.sort_values([cnty,ryr],ascending=False) 

... aber ich weiß, ich brauche ‚Kreis‘ zugreifen anders, da es nicht ist eine echte Spalte.

Update:

ich das letzte Jahr Prozent berechnen können (und herauszufiltern) durch Umsetzung und Gruppe unter Verwendung von, obwohl ich bin sicher, dass es eine effizientere Art und Weise.

d=d2.T 
d['Percent']=(d.iloc[:,-1]/d.iloc[:,-1].sum()*100) 

Vielen Dank im Voraus!

Antwort

1

Sie könnten:

df = pd.concat([df, df.groupby(level='County').apply(lambda x: x['2013'].div(x['2013'].sum())).reset_index(0, drop=True).to_frame('Percent')], axis=1) 
top_3 = df.groupby(level='County')['Percent'].nlargest(3).reset_index(0, drop=True) 
df = pd.concat([df.drop('Percent', axis=1), top_3], axis=1, join='inner') 
df.groupby(level=1).apply(lambda x: x.sort_values('Percent', ascending=False)).reset_index(0, drop=True).T 

zu erhalten:

    A        B      
       d   e   b   e   a   b 
Year                  
2012  57.000000 95.000000 55.000000 81.000000 54.000000 27.000000 
2013  89.000000 76.000000 65.000000 67.000000 34.000000 12.000000 
Percent 0.289902 0.247557 0.211726 0.587719 0.298246 0.105263 
+0

Dank. Auch das: d.sort_values ​​(d2.T.columns [-1], aufsteigend = False) .sortlevel (1, sort_remaining = False) wie von Jezrael hier angezeigt: http://stackoverflow.com/questions/37147822/pandas -pivot-table-nested-sorting/37148717? noredirect = 1 # comment61837435_37148717 –

+1

siehe aktualisierte Antwort. – Stefan

0

So fand ich, dass dies funktioniert auch:

d=d2.T 
d['Percent']=round(d.iloc[:,-1]/d.iloc[:,-1].groupby(level=1).transform(sum),2) 
d=d.sort_values(d.columns[-1],ascending=False).sortlevel(1, sort_remaining=False) 
d=d.groupby(level=1).head(3) 
d.T