朱莉娅版的R's Match?

时间:2015-09-01 14:24:19

标签: r julia

来自R的match()帮助页面:

说明

 ‘match’ returns a vector of the positions of (first) matches of
 its first argument in its second.

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

朱莉娅有这么类似的功能吗?我找不到了。

2 个答案:

答案 0 :(得分:6)

听起来你正在寻找indexin(就像搜索饲料一样,这也被Matlab称为ismember)。它略有不同:它返回一个向量,其中第i个元素是 last 索引,其中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

它为v1中未出现在v2中的元素的索引返回零。因此,您只需通过非零索引索引即可“重建”v1v2的部分:

julia> v2[idxs[idxs .> 0]]
3-element Array{Int64,1}:
 8
 6
 7

如果查看the implementation,您会看到它使用字典来存储和查找索引。这意味着它只对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 :(得分: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,因为在Base中定义了match用于字符串匹配,如果要扩展它,则必须先导入Base.match。如果你关心表现,你当然可以更快地应用Julia docs表演部分的一些技巧 如果我理解正确的话,这个功能应该是你正在寻找的东西,尝试用例如。

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