You can use groupby with apply difference max and min if length is more as 1 else 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
I think instead max you can use iloc too:
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
Another solution with Series.where, which 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