JKHA
JKHA

Reputation: 1896

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?

Upvotes: 4

Views: 3584

Answers (2)

carstenbauer
carstenbauer

Reputation: 10147

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.

Upvotes: 5

This was very helpful. For fun, I wasnted to sum up the ascii codes for all the caracters in a drring in a single line and it helped me figure it out. x is a string, e.g., "MyImage.gif.":

#y = collect(x)
#leny = length(y)
#Ltot = 0         # leny
#for i = 1 : leny
#    Ltot += Int32(y[i])
#end
Ltot = sum(map(Int32, collect(x)))    # Fun!

Upvotes: 0

Related Questions