2016-05-07 18 views
2

folgender Datenrahmen Gegeben:Pandas Perzentil Feld auf groupby mit Niveau basierend erstellen 1

import pandas as pd  
df = pd.DataFrame({ 
    ('Group', 'group'): ['a','a','a','b','b','b'], 
    ('sum', 'sum'): [234, 234,544,7,332,766] 
    }) 

Ich mag ein neues Feld erstellen, das die Perzentil jeden Wert von „sum“ pro Gruppe berechnet in " Gruppe". Das Problem ist, ich habe 2 Header Spalten und kann nicht herausfinden, wie der Fehler zu vermeiden, bekommen:

ValueError: level > 0 only valid with MultiIndex 

wenn ich laufe dies:

df=df.groupby('Group',level=1).sum.rank(pct=True, ascending=False) 

Ich brauche die Header in der gleichen Struktur zu halten.

Vielen Dank im Voraus!

Antwort

2

Zur Gruppe der ersten Spalte, ('Group', 'group'), und berechnen den Rang für die ('sum', 'sum') Spalte Verwendung:

In [106]: df['rank'] = (df[('sum', 'sum')].groupby(df[('Group', 'group')]).rank(pct=True, ascending=False)) 

In [107]: df 
Out[107]: 
    Group sum  rank 
    group sum   
0  a 234 0.833333 
1  a 234 0.833333 
2  a 544 0.333333 
3  b 7 1.000000 
4  b 332 0.666667 
5  b 766 0.333333 

anzumerken, dass .rank(pct=True) einen Rang Prozentsatz berechnet, nicht eine Perzentil. Um ein Perzentil zu berechnen, können Sie scipy.stats.percentileofscore verwenden.

import scipy.stats as stats 
df['percentile'] = (df[('sum', 'sum')].groupby(df[('Group', 'group')]) 
    .apply(lambda ser: 100-pd.Series([stats.percentileofscore(ser, x, kind='rank') 
      for x in ser], index=ser.index))) 

ergibt

Group sum  rank percentile 
    group sum      
0  a 234 0.833333 50.000000 
1  a 234 0.833333 50.000000 
2  a 544 0.333333 0.000000 
3  b 7 1.000000 66.666667 
4  b 332 0.666667 33.333333 
5  b 766 0.333333 0.000000