Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Julia: find row in matrix

Tags:

matrix

julia

Using Julia, I'd like to determine if a row is located in a matrix and (if applicable) where in the matrix the row is located. For example, in Matlab this can done with ismember:

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

 3     1     2
 2     1     3
 1     2     3
 2     3     1

ismember(B, a, 'rows')
ans =

 0
 0
 1
 0

From this, we can see a is located in row 3 of B. Is there a similar function to accomplish this in Julia?

like image 265
Adam Avatar asked Sep 22 '15 01:09

Adam


4 Answers

You can also make use of array broadcasting by simply testing for equality (.==) without the use of comprehensions:

all(B .== a, dims=2)

Which gives you:

4x1 BitMatrix:
 0
 0
 1
 0

You can then use findall on this array:

findall(all(B .== a, 2))

However, this gives you a vector of CartesianIndex objects:

1-element Vector{CartesianIndex{2}}:
 CartesianIndex(3, 1)

So if you expect to find multiple rows with the value defined in a you can either:

  1. simplify this Vector by taking only the row index from each CartesianIndex:

    [cart_idx[1] for cart_idx in findall(all(B .== a, 2))]
    
  2. or pass one dimensional BitMatrix to findall (as suggested by Shep Bryan in the comment):

    findall(all(B .== a, dims=2)[:, 1])
    

Either way you get an integer vector of column indices:

1-element Vector{Int64}:
 3
like image 165
mmagnuski Avatar answered Nov 12 '22 22:11

mmagnuski


Another pattern is using array comprehension:

julia> Bool[ a == B[i,:] for i=1:size(B,1) ]
4-element Array{Bool,1}:
false
false
true
false

julia> Int[ a == B[i,:] for i=1:size(B,1) ]
4-element Array{Int64,1}:
0
0
1
0
like image 6
roygvib Avatar answered Nov 12 '22 20:11

roygvib


how about:

matchrow(a,B) = findfirst(i->all(j->a[j] == B[i,j],1:size(B,2)),1:size(B,1))

returns 0 when no matching row, or first row number when there is one.

matchrow(a,B)

3

should be as "fast as possible" and pretty simple too.

like image 6
Dan Getz Avatar answered Nov 12 '22 21:11

Dan Getz


Though Julia doesn't have a built-in function, its easy enough as a one-liner.

a = [1 2 3];
B = [3 1 2; 2 1 3; 1 2 3; 2 3 1]
ismember(mat, x, dims) = mapslices(elem -> elem == vec(x), mat, dims)
ismember(B, a, 2)  # Returns booleans instead of ints
like image 5
ntdef Avatar answered Nov 12 '22 21:11

ntdef