Search code examples
sortingmatrixjuliaranking

Ranking over each matrix column's sort in julia


I have a matrix (m) of scores for 4 students on 3 different exams.

4 3 1
3 2 5
8 4 6
1 5 2

I want to know, for each student, the exams they did best to worse on. Desired output:

1 2 3
2 3 1
1 3 2
3 1 2

Now, I'm new to the language (and coding in general), so I read GeeksforGeeks' page on sorting in Julia and tried

mapslices(sortperm, -m; dims = 2)

However, this gives something subtly different: a matrix of each row being the index of the sorting.

1 2 3
3 1 2
1 3 2
2 3 1

Perhaps it was obvious, but I now realize this is not actually what I want, but I cannot find a built-in function/fast way to complete this operation. Any ideas? Preferably something which doesn't iterate through items in the matrix/row, as in reality my matrix is very, very large. Thanks!


Solution

  • Such functionality is provided by StatsBase.jl. Here is an example:

    julia> using StatsBase
    
    julia> m = [4 3 1
                3 2 5
                8 4 6
                1 5 2]
    4×3 Array{Int64,2}:
     4  3  1
     3  2  5
     8  4  6
     1  5  2
    
    julia> mapslices(x -> ordinalrank(x, rev=true), m, dims = 2)
    4×3 Array{Int64,2}:
     1  2  3
     2  3  1
     1  3  2
     3  1  2
    

    You might want to use other rank, depending on how you want to split ties, see here for details.