Reputation: 63
I have a dataframe with multiple columns, each of which has their own value.
data = {'name' : ['bill', 'joe', 'steve'],
'test1' : [7, 75, 85],
'test2' : [35, 45, 83],
'test3' : [51, 61, 45]}
df = pd.DataFrame(data)
name test1 test2 test3
0 bill 7 35 51
1 joe 75 45 61
2 steve 85 83 45
I would like to replace the values in some of the columns with relative rank across the row rather than actual value. The output would be as follows.
name test1 test2 test3
0 bill 3 2 1
1 joe 1 3 2
2 steve 1 2 3
Is there a way to do this?
Upvotes: 3
Views: 1597
Reputation: 294278
a = np.argsort(df.iloc[:, 1:].to_numpy(), axis=1)
n, m = a.shape
b = np.empty_like(a)
c, d = np.mgrid[:n, :m]
b[c, a] = m - d
df.iloc[:, 1:] = b
df
name test1 test2 test3
0 bill 3 2 1
1 joe 1 3 2
2 steve 1 2 3
Upvotes: 3
Reputation: 117691
>>> df.rank("columns", ascending=False)
test1 test2 test3
0 3.0 2.0 1.0
1 1.0 3.0 2.0
2 1.0 2.0 3.0
>>> rankcols = ["test1", "test2", "test3"]
>>> df[rankcols] = df[rankcols].rank("columns", ascending=False).astype(int)
>>> df
name test1 test2 test3
0 bill 3 2 1
1 joe 1 3 2
2 steve 1 2 3
Upvotes: 2
Reputation: 38415
You can use DataFrame.rank
on axis 1
df = df.assign(**df.iloc[:, 1:].rank(axis = 1, ascending = False).astype(int))
name test1 test2 test3
0 bill 3 2 1
1 joe 1 3 2
2 steve 1 2 3
Upvotes: 7