R的Match函数在Julia中有对应的版本吗?

6

来自R的帮助页面match()

描述:

‘match’返回第一个参数在第二个参数中(第一次)匹配的位置向量。

也就是说,我可以给出两个向量,match(v1,v2)返回一个向量,其中第i个元素是v1[i]v2中出现的索引。

是否有类似于Julia的函数?我找不到它。


1
https://dev59.com/UGIj5IYBdhLWcg3wmWC1 - Khashaa
2个回答

7
看起来你需要的是 indexin (Matlab 中也称为ismember),它非常略微地不同:它返回一个向量,其中第 i 个元素是 v1[i]v2 中出现的最后一个索引。
julia> v1 = [8,6,7,11]; v2 = -10:10;
       idxs = indexin(v1, v2)
4-element Array{Int64,1}:
 19
 17
 18
  0

如果在v2中没有出现v1元素的索引,则返回零。因此,您可以通过非零索引来“重建”在v2中的v1部分。
julia> v2[idxs[idxs .> 0]]
3-element Array{Int64,1}:
 8
 6
 7

如果您查看实现,您会发现它使用字典存储和查找索引。这意味着它每个元素只需要经过一次v1v2,而不是在v2中搜索每个v1的元素。在几乎所有情况下,这应该更有效率。

如果匹配R的行为并返回第一个索引很重要,我们可以抄袭基本实现并向后构建字典,以便较低的索引覆盖较高的索引:

function firstindexin(a::AbstractArray, b::AbstractArray)
    bdict = Dict{eltype(b), Int}()
    for i=length(b):-1:1
        bdict[b[i]] = i
    end
    [get(bdict, i, 0) for i in a]
end

julia> firstindexin([1,2,3,4], [1,1,2,2,3,3])
4-element Array{Int64,1}:
 1
 3
 5
 0

julia> indexin([1,2,3,4], [1,1,2,2,3,3])
4-element Array{Int64,1}:
 2
 4
 6
 0

1
indexin 在 0.7/1.0 中有所改变,现在在没有匹配项时返回 nothing - catastrophic-failure

4

我认为这个功能原生并不存在,但正如@Khashaa的评论(以及Tim Holy对另一个问题的答案)指出的那样,你应该能够很快地想出自己的定义。首先尝试一下:

function matched(v1::Array, v2::Array)
  matched = zeros(length(v1))
  for i = 1:length(v1)
    matched[i] = findfirst(v2, v1[i])
  end
  return matched
end

(请注意,我将函数称为matched,因为match在Base中已定义用于字符串匹配,如果您想扩展它,首先必须导入Base.match)。如果您关心性能,可以应用Julia文档的性能部分中的一些技巧来使其更快。
如果我理解正确,这个函数应该做你想要的事情,请尝试使用例如:

v1 = [rand(1:10) for i = 1:100]
v2 = [rand(1:10) for i = 1:100]
matched2(v1,v2)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接