Matrix 朱莉娅:在矩阵中找到行

Matrix 朱莉娅:在矩阵中找到行,matrix,julia,Matrix,Julia,使用Julia,我想确定一行是否位于矩阵中,以及(如果适用)该行在矩阵中的位置。例如,在Matlab中,可以使用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 由此,我们可以看到a位于B的第3行。Julia中是否有类似

使用Julia,我想确定一行是否位于矩阵中,以及(如果适用)该行在矩阵中的位置。例如,在Matlab中,可以使用
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

由此,我们可以看到
a
位于
B
的第3行。Julia中是否有类似的函数来实现这一点?

虽然Julia没有内置函数,但作为一个线性函数,它已经足够简单了

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

另一种模式是使用数组理解:

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

您还可以通过简单地测试相等性(
==
)来使用阵列广播,而无需使用理解:

all(B .== a, 2)
这给了你:

4x1 BitArray{2}:
 false
 false
  true
 false
然后可以在此数组上使用find来获取行的索引:

find(all(B .== a, 2))
你会得到:

1-element Array{Int64,1}:
 3
那么:

matchrow(a,B) = findfirst(i->all(j->a[j] == B[i,j],1:size(B,2)),1:size(B,1))
如果没有匹配行,则返回
0
,如果有匹配行,则返回第一行号

matchrow(a,B)
三,


应该是“尽可能快”且非常简单。

此解决方案和@freshfruit的解决方案具有相似的运行时,但此解决方案似乎占用更少的内存。多亏了这两个!在
B
中,行
a
的位置可以通过
find(Bool[a==B[i,对于i=1:size(B,1)])找到
。但是,这会产生类型为
Array{Int64,1}
的结果,而不是
Int64
。结果是一个
数组{Int64,1}
会让人头疼。除了
查找(Bool[a==B[i,:]对于i=1:size(B,1)])[1]
之外,还有没有更好的方法来获得
Int64
的结果呢?在其他答案之后,findfirst()可能会对这一目的很有用。例如,
findfirst([a==B[i,i:]表示i=1:size(B,1)])
(有理解)或
findfirst(all(a==B,2))
(有广播)。而且,我们可以把布尔放在[…]前面更简单一点:)我感兴趣的是这个问题的版本,其中B使用其行的字典顺序进行排序,搜索以对数时间返回。这在Julia 1.1.0中有效,而其他答案没有。如果在Julia>1.0中,当没有匹配行时,此函数将返回
nothing