2016-09-07 7 views
2

Ich habe diese TabellePython Pandas Gruppe von Funktion

uname sid usage 
0 Ahmad a 5 
1 Ahmad a 7 
2 Ahmad a 10 
3 Ahmad b 2 
4 Mohamad c 6 
5 Mohamad c 7 
6 Mohamad c 9 

ich von uname und Seite gruppieren möchten und Nutzungs Spalte = group.max-group.min. Aber wenn Gruppenzählwert ist 1 Rückkehr Gruppe max

der aus Put- sollte

uname sid usage 
0 Ahmad a 5 
1 Ahmad b 2 
2 Mohamad c 3  

Antwort

1

Zuerst agg verwenden min, max und size jeder Gruppe zu greifen.
Dann multiplizieren min von size > 1. Wenn es ist, wird es gleich min, sonst 0. Dann subtrahiere das von max.

d1 = df.groupby(['uname', 'sid']).usage.agg(['min', 'max', 'size']) 
d1['max'].sub(d1['min'].mul(d1['size'].gt(1))).reset_index(name='usage') 

enter image description here

+1

vielleicht besser verwenden 'd1 [ 'max']. Sub (d1 [ 'min']. Mul (d1 [ 'size']. Gt (1))). Reset_index (name = 'usage') ' – jezrael

+0

@jezrael tyvm .. – piRSquared

1

Sie groupby mit apply Unterschied verwenden können max und min wenn length mehr als 1 ist sonst max:

df = df.groupby(['uname','sid'])['usage'] 
     .apply(lambda x: x.max()-x.min() if len(x) > 1 else x.max()) 
     .reset_index() 
print (df) 
    uname sid usage 
0 Ahmad a  5 
1 Ahmad b  2 
2 Mohamad c  3 

Ich denke stattdessen max können Sie iloc auch verwenden :

df = df.groupby(['uname','sid'])['usage'] 
     .apply(lambda x: x.max()-x.min() if len(x) > 1 else x.iloc[0]) 
     .reset_index() 
print (df) 
    uname sid usage 
0 Ahmad a  5 
1 Ahmad b  2 
2 Mohamad c  3 

Eine andere Lösung mit Series.where, die Test size:

g = df.groupby(['uname','sid'])['usage'] 
s = g.max()-g.min() 
print (s) 
uname sid 
Ahmad a  5 
     b  0 
Mohamad c  3 
Name: usage, dtype: int64 

print (g.size() == 1) 
uname sid 
Ahmad a  False 
     b  True 
Mohamad c  False 
dtype: bool 

print (s.where(g.size() != 1, g.max()).reset_index()) 
    uname sid usage 
0 Ahmad a  5 
1 Ahmad b  2 
2 Mohamad c  3 
Verwandte Themen