1
votes

How can matrices be sorted in Julia.

Let's define a matrix:

a = [1 1 1;
     1 3 1;
     1 2 2;
     1 2 1]

I'm looking for several things here:

Sort by multiple Columns

So, you can sort the matrix by all columns from left to right with

sortslices(a, dims = 1)

4×3 Array{Int64,2}:
 1  1  1
 1  2  1
 1  2  2
 1  3  1

Sort by particular Column Order

But what if want to sort by the 3rd then the 2nd and then the 1st column? Expected output:

4×3 Array{Int64,2}:
 1  1  1
 1  2  1
 1  3  1
 1  2  2

Sort permutation

Let's assume I had a Vector

b = ["a", "d", "c", "b"]

and I would like to sort its elements by the sort permutation of the matrix' columns. As seen above sortslices() let's me sort the matrix so I get the rows in the order [1,4,3,2]. How can I get this vector to sort b to

4-element Array{String,1}:
 "a"
 "b"
 "c"
 "d"

I know there are other similar questions, but they seem either address other issues or they seem to be outdated (e.g. Julia: Sort Matrix by column 2 then 3).

2

2 Answers

3
votes

It isn't ideal to ask multiple questions within a single post. It makes searching for questions much harder.

Anyway, here we go:

Sort by multiple Columns

julia> a = [1 1 1;
            1 3 1;
            1 2 2;
            1 2 1]
4×3 Matrix{Int64}:
 1  1  1
 1  3  1
 1  2  2
 1  2  1

julia> sortslices(a, dims = 1, by=x->(x[1], x[2], x[3]))
4×3 Matrix{Int64}:
 1  1  1
 1  2  1
 1  2  2
 1  3  1

Sort by particular Column Order

julia> a = [1 1 1;
            1 3 1;
            1 2 2;
            1 2 1]
4×3 Matrix{Int64}:
 1  1  1
 1  3  1
 1  2  2
 1  2  1

julia> sortslices(a, dims = 1, by=x->(x[3], x[2], x[1]))
4×3 Matrix{Int64}:
 1  1  1
 1  2  1
 1  3  1
 1  2  2

Sort permutation

julia> b = ["a", "d", "c", "b"]
4-element Vector{String}:
 "a"
 "d"
 "c"
 "b"

julia> sortperm(b)
4-element Vector{Int64}:
 1
 4
 3
 2

julia> b[sortperm(b)]
4-element Vector{String}:
 "a"
 "b"
 "c"
 "d"
0
votes

Building on @mcabbot's comment, I think that by clause is unnecessary. This suffices: p = sortperm(collect(eachrow(a))).

Whether this is the most performant solution, I don't know.