2017-09-03 2 views
1

Ich habe folgende DatenrahmenKategorie auf Zuweisen basierend Perzentil

Group Country GDP 

    A  a  *** 
    A  b  *** 
    B  a  *** 
    B  b  *** 

I catagory zu gdp zuweisen möchten (High, Low) auf Basis innerhalb der Gruppe Perzentilrang durch eine neue Spalte zu schaffen. Dies ist, was ich versucht

def c(gr): 
     ser=gr['gdp'] 
     p=np.nanpercentile(ser,50) 
     for i in ser: 
      if i>p: 
       return "high" 
      else: 
       return "low" 

grouped = df.groupby('Group') 
df['perf']=grouped.apply(c) 

Perf Spalte nan zurückkehrt. Was mache ich hier falsch?

+1

Haben Sie sich 'pd.cut'? –

+0

Hallo, ich gebe die Lösung, es ist ähnlich mit R :) – Wen

Antwort

3

Verwenden quantile mit numpy.where und benutzerdefinierte Funktion:

def c(gr): 
    ser=gr['gdp'] 
    #q=0.5 is by default, so can be omit 
    p = ser.quantile() 
    gr['perf'] = np.where(ser > p, 'high', 'low') 
    return gr 

df = df.groupby('Group').apply(c) 

Dies wird durch transform vereinfacht werden kann:

q = df.groupby('Group')['gdp'].transform('quantile') 
df['perf1'] = np.where(df['gdp'] > q, 'high', 'low') 

Probe:

np.random.seed(12) 

N = 15 
L = list('abcd') 
df = pd.DataFrame({'Group': np.random.choice(L, N), 
        'gdp': np.random.rand(N)}) 
df = df.sort_values('Group').reset_index(drop=True) 
df.loc[[0,4,5,10,13,14], 'gdp'] = np.nan 
#print (df) 

def c(gr): 
    ser=gr['gdp'] 
    #q=0.5 is by default, so can be omit 
    p = ser.quantile() 
    gr['perf'] = np.where(ser > p, 'high', 'low') 
    return gr 

df = df.groupby('Group').apply(c) 

q = df.groupby('Group')['gdp'].transform('quantile') 
df['perf1'] = np.where(df['gdp'] > q, 'high', 'low') 
print (df) 
    Group  gdp perf perf1 
0  a  NaN low low 
1  a 0.907267 high high 
2  a 0.456051 low low 
3  b 0.675998 low low 
4  b  NaN low low 
5  b  NaN low low 
6  b 0.563141 low low 
7  b 0.801265 high high 
8  c 0.372834 low low 
9  c 0.481530 high high 
10  c  NaN low low 
11  d 0.082524 low low 
12  d 0.725954 high high 
13  d  NaN low low 
14  d  NaN low low 
+0

Um weitere Bedingungen hinzuzufügen, mache ich folgendes: def tr (group): ser = gruppe ['gdp']. Dropna() für i in ser: wenn i> (ser.quantil (q = 0,75)): Gruppe ['perf'] = "h" elif i <(ser.quantile (q = .25)): Gruppe ['perf'] = "l" sonst: Gruppe [ 'perf'] = "m" return Gruppe (dies wird alle gdp als "h" Rückkehr) – mezz

+1

Sorry, völlig vergessen, die ich. Das beste ist 'q1 = df.groupby ('Group') ['gdp']. Transform (Lambda x: x.quantile (q = .75))' 'q2 = df.groupby ('Group') [' GDP '] zu transformieren. (lambda x: x.quantile (q = .25)) '' und dann df [' Perf1 '] = np.where (df [' GDP ']> q1 ' h', np.where (df ​​['gdp'] jezrael

1

Ähnliche mit R

df['output']=df.groupby('Group').gdp.apply(lambda x : np.where(x>x.quantile(0.75),'High','Low')).apply(pd.Series).stack().dropna().values 

df 
Out[333]: 
    Group  gdp output 
0  a  NaN Low 
1  a 0.772128 Low 
2  a 0.070406 Low 
3  a 0.859301 High 
4  a  NaN Low 
5  a  NaN Low 
6  b 0.681299 High 
7  b 0.040839 Low 
8  c 0.896475 High 
9  c 0.726527 Low 
10  c  NaN Low 
11  c 0.244783 Low 
12  c 0.563001 Low 
13  c  NaN Low 
14  d  NaN Low 
Verwandte Themen