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