twist dataframe by rank
<p>consider the dataframe <code>df</code></p>

<pre><code>np.random.seed([3,1415])
df = pd.DataFrame(np.random.rand(4, 5), columns=list('ABCDE'))
df
</code></pre>

<p><a href="http://i.stack.imgur.com/VuXYh.png" rel="nofollow"><img src="http://i.stack.imgur.com/VuXYh.png" alt="enter image description here"></a></p>

<hr>

<p>I want a dataframe where the columns are ranks and each row is <code>['A', 'B', 'C', 'D', 'E']</code> in rank order.</p>

<p><strong><em>ranks</em></strong>  </p>

<pre><code>df.rank(1).astype(int)
</code></pre>

<p><a href="http://i.stack.imgur.com/VkC62.png" rel="nofollow"><img src="http://i.stack.imgur.com/VkC62.png" alt="enter image description here"></a></p>

<hr>

<p><strong><em>expected results</em></strong></p>

<p><a href="http://i.stack.imgur.com/UtYAi.png" rel="nofollow"><img src="http://i.stack.imgur.com/UtYAi.png" alt="enter image description here"></a></p>

<p>Here's one way:</p>

<pre><code>In [90]: df
Out[90]: 
          A         B         C         D         E
0  0.444939  0.407554  0.460148  0.465239  0.462691
1  0.016545  0.850445  0.817744  0.777962  0.757983
2  0.934829  0.831104  0.879891  0.926879  0.721535
3  0.117642  0.145906  0.199844  0.437564  0.100702

In [91]: df2 = df.apply(lambda row: df.columns[np.argsort(row)], axis=1)

In [92]: df2
Out[92]: 
   A  B  C  D  E
0  B  A  C  E  D
1  A  E  D  C  B
2  E  B  C  D  A
3  E  A  B  C  D
</code></pre>

<p>The new DataFrame has the same column index as <code>df</code>, but that can be fixed:</p>

<pre><code>In [93]: df2.columns = range(1, 1 + df2.shape[1])

In [94]: df2
Out[94]: 
   1  2  3  4  5
0  B  A  C  E  D
1  A  E  D  C  B
2  E  B  C  D  A
3  E  A  B  C  D
</code></pre>

<hr>

<p>Here's another way.  This one converts the DataFrame to a numpy array, applies <code>argsort</code> on axis 1, uses that to index <code>df.columns</code>, and puts the result back into a DataFrame.</p>

<pre><code>In [110]: pd.DataFrame(df.columns[np.array(df).argsort(axis=1)], columns=range(1, 1 + df.shape[1]))
Out[110]: 
   1  2  3  4  5
0  B  A  C  E  D
1  A  E  D  C  B
2  E  B  C  D  A
3  E  A  B  C  D
</code></pre>

python pandas numpy