Search code examples
matrixjulia

Apply a function to every column of a matrix


What is the most efficient and concise way to apply a function to each column (or row) of a matrix?

Suppose I have a matrix, and to simplify, a minimal working matrix:

julia> mtx
4×2 Array{Float64,2}:
    1.0     8.0
 -Inf       5.0
    5.0  -Inf
    9.0     9.0

Let's say you have to apply sortperm to each column of mtx.

For sure it can be done by:

for i in 1:size(mtx)[2]
    mtx[:,i] = sortperm(mtx[:,i])
end

 julia> mtx
4×2 Array{Float64,2}:
 2.0  3.0
 1.0  2.0
 3.0  1.0
 4.0  4.0

But isn't there a more concise way, with map or something similar? Finally, can you please tell me how I could have find it myself by searching which keywords on Julia's documentation?


Solution

  • You are looking for mapslices:

    julia> mtx = [1.0 8.0;-Inf 5.0;5.0 -Inf;9.0 9.0]
    4×2 Array{Float64,2}:
        1.0     8.0
     -Inf       5.0
        5.0  -Inf
        9.0     9.0
    
    julia> mapslices(sortperm, mtx; dims=1) # apply sortperm to every column of mtx
    4×2 Array{Int64,2}:
     2  3
     1  2
     3  1
     4  4
    

    Taken from the documentation:

    Transform the given dimensions of array A using function f. f is called on each slice of A of the form A[...,:,...,:,...]. dims is an integer vector specifying where the colons go in this expression. The results are concatenated along the remaining dimensions. For example, if dims is [1,2] and A is 4-dimensional, f is called on A[:,:,i,j] for all i and j.