I have a matrix that I would like to replace the values of each column with where they are in an ordered list of values from least to greatest. For example, if I have


I would like to transform it to


I understand how SortBy and Replace work, but I'm not sure how to use them together to in this case, since I do not actually want to values sorted in the end.

Transpose[Ordering@Ordering@# & /@ Transpose@m]  

{{2, 2}, {1, 3}, {3, 1}}


jjc385 suggests this neat modification:

Transpose[Ordering@*Ordering /@ Transpose@m]  

{{2, 2}, {1, 3}, {3, 1}}

  • 1
    $\begingroup$ You beat me by a minute! I personally find it cleaner to use Composition (@*) rather than a pure function in cases like this. +1 $\endgroup$
    – jjc385
    Feb 12 '18 at 19:28

Let's start with a single column: col = {0.5, 0.2, 0.7}. Applying Ordering to it gives

Ordering @ col
{2, 1, 3}

This tells us the smallest element is at position 2 in the original list, the next smallest is at position 1, and the largest is at position 3. This isn't quite what we want, but we can get that by applying InversePermutation :

InversePermutation @ Ordering @ col
{2, 1, 3}

(The last example in 'Properties & Relations' in the docs for InversePermutation might be helpful.)

To do this for the columns of the matrix, you can transpose, apply this procedure, and transpose the result:

Transpose @* Map[ InversePermutation @* Ordering ] @* Transpose @ m
{{2, 2}, {1, 3}, {3, 1}}
SameQ[%, m2]
  • $\begingroup$ Thanks, this has worked great! $\endgroup$
    – Megan
    Feb 20 '18 at 20:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.