Find julia in matrix with (row, col) instead of index

In Julia, you can find the coordinates of the elements in the matrix via:

julia> find( x -> x == 2, [ 1 2 3; 2 3 4; 1 0 2] ) 3-element Array{Int64,1}: 2 4 9 

These values ​​are correct, but I would prefer that instead I get (row, col) tuples.

 (1,2) (2,1) (3,3) 

What is the easiest way to achieve this in Julia?

+5
source share
4 answers

I do not believe that there is a built-in way to do this, but here is a function to do this

 function findmat(f, A::AbstractMatrix) m,n = size(A) out = (Int,Int)[] for i in 1:m, j in 1:n f(A[i,j]) && push!(out,(i,j)) end out end 

eg.

 julia> findmat(x->x==2, [ 1 2 3; 2 3 4; 1 0 2] ) 3-element Array{(Int64,Int64),1}: (1,2) (2,1) (3,3) 

If a large number of elements satisfies the condition, it would be more efficient to do this in two passes, but I doubt it.

+4
source

The closest thing I can find in the Julia standard library is findn :

 julia> A = [1 2 3; 2 3 4; 1 0 2] 3x3 Array{Int64,2}: 1 2 3 2 3 4 1 0 2 julia> findn(A .== 2) ([2,1,3],[1,2,3]) 

This gives a set of vectors instead of a tuple vector.

Another thing to note is that the match in (2,1) reported before what is in (1,2) . This is due to the fact that the arrays in Julia are stored in the main column order, so scanning the array A in the storage order will look at position (2,1) to (1,2) .

+3
source

if you want to avoid defining "new" functions, perhaps:

 collect(zip(ind2sub((3,3),find( x -> x == 2, [ 1 2 3; 2 3 4; 1 0 2] ))...)) 

- this is what you are looking for. (3.3) implicit in matrix size. if the matrix was given by a variable, it would look more natural with size(M)

+2
source

In case anyone else finds this, you can now use:

 ind2sub(a, index) 

It returns a tuple of indices in the array a corresponding to the linear index index

+2
source

Source: https://habr.com/ru/post/1204019/


All Articles