Finding Position of Element in an Array

question

#1

I’m looking for a function (is there is one) where i can get the position of an element in an array? I have a 3D array of numbers and i want to obtain the position (i,j,k)of a particular number (element) in that array. Is there a way to obtain it? Thanks in advance.


#2

The following works on Julia 0.6:

julia> A = rand(1:3, 3, 3, 3)
3×3×3 Array{Int64,3}:
[:, :, 1] =
 2  3  2
 2  2  2
 2  1  3

[:, :, 2] =
 3  3  3
 2  1  3
 3  1  1

[:, :, 3] =
 3  2  1
 2  2  2
 3  1  1

julia> findall(x->x==2, A)
11-element Array{CartesianIndex{3},1}:
 CartesianIndex(1, 1, 1)
 CartesianIndex(2, 1, 1)
 CartesianIndex(3, 1, 1)
 CartesianIndex(2, 2, 1)
 CartesianIndex(1, 3, 1)
 CartesianIndex(2, 3, 1)
 CartesianIndex(2, 1, 2)
 CartesianIndex(2, 1, 3)
 CartesianIndex(1, 2, 3)
 CartesianIndex(2, 2, 3)
 CartesianIndex(2, 3, 3)

#3

Thank you for the prompt response. I tried it but i get the following error:

findall(x->x==2, A)
ERROR: UndefVarError: findall not defined

Apratently i dont have that function. When i look the function it tells me:

Binding findall does not exis


#4

findall is the name in version 0.7. In version 0.6 you just use find instead.


#5

I used find and i get the following:

find(x->x==2, A)
10-element Array{Int64,1}:
1
5
10
11
12
14
17
19
26
27

What i need is the position (CartesianIndex). What am I doing wrong?


#6

…i want to obtain the position (i,j,k)of a particular number (element) in that array.

ind2sub(A, find(A .== 2))

EDIT (for v0.6)

i, j, k = ind2sub(A, find(x->x == 2,A))
idx = [i  j  k]

#7

Is there a mode for findall() in 0.7 which works with linear indices?


#8

It is normally preferable to use find(x->x==2, A) over find(A.==2).


#9

You can convert, something like

julia> v = rand(3,3);

julia> C = findall(x->x>0.5, v)
5-element Array{CartesianIndex{2},1}:
 CartesianIndex(2, 1)
 CartesianIndex(2, 2)
 CartesianIndex(3, 2)
 CartesianIndex(2, 3)
 CartesianIndex(3, 3)

julia> L = LinearIndices(v)
3×3 LinearIndices{2,Tuple{Base.OneTo{Int64},Base.OneTo{Int64}}}:
 1  4  7
 2  5  8
 3  6  9

julia> L[C]
5-element Array{Int64,1}:
 2
 5
 6
 8
 9

Converting a Matlab code into Julia
#10

As wrote Kristoffer:

(LinearIndices(A))[findall(x->x == 2, A)]


#11

You can also do

julia> C = findall(x->x>0.5, vec(v))
3-element Array{Int64,1}:
 1
 2
 4

#12

Is it efficient?
Could we not add mode for findall() to iterate to through all elements in one loop?

Does Julia have more efficient way to work on the array (Like looping on its length)?


#13

I think Kristoffer solved this problem:


#14

Thanks to you all. Since I don,'t have findall, I tried ind2sub(A, find(A == 2)) and it worked!!


#15

How does it compare to something like:

y = [i for i ∈ 1:length(x) if x[i] > 0.5];


#16

Try it and see?
[Put both in functions and use BenchmarkTools.jl.]