julia中的矢量化"in"功能?

ARM*_*ARM 7 vectorization dataframe julia

我经常想要遍历数据帧的长数组或列,并为每个项目查看它是否是另一个数组的成员.而不是做

giant_list = ["a", "c", "j"]
good_letters = ["a", "b"]
isin = falses(size(giant_list,1))
for i=1:size(giant_list,1)
    isin[i] = giant_list[i] in good_letters
end
Run Code Online (Sandbox Code Playgroud)

是否有任何矢量化(双向矢量?)方式在朱莉娅这样做?与基本操作符类似,我想做类似的事情

isin = giant_list .in good_letters
Run Code Online (Sandbox Code Playgroud)

我意识到这可能是不可能的,但我只是想确保我没有遗漏一些东西.我知道我可能会使用DataStructures中的DefaultDict做类似但不知道基础中的任何内容.

Mat*_* B. 7

indexin函数执行类似于您想要的操作:

indexin(a, b)

返回包含在最高索引的向量b对于中的每个值a是的成员b.输出向量包含0,a而不是其中的成员b.

由于您需要为您的每个元素giant_list(而不是索引good_letters)中的每个元素设置一个布尔值,您可以简单地执行:

julia> indexin(giant_list, good_letters) .> 0
3-element BitArray{1}:
  true
 false
 false
Run Code Online (Sandbox Code Playgroud)

实施indexin是非常简单的,而且指明了道路可能会如何优化这个,如果你不关心的指标b:

function vectorin(a, b)
    bset = Set(b)
    [i in bset for i in a]
end
Run Code Online (Sandbox Code Playgroud)

只有一组有限的名称可以用作中缀运算符,因此无法将其用作中缀运算符.


Har*_*din 6

有一些现代(即Julia v1.0)解决方案可以解决此问题:

首先,对标量策略进行更新。可以使用一个Ref对象来实现标量广播,而不是使用1元素的元组或数组:

julia> in.(giant_list, Ref(good_letters))
3-element BitArray{1}:
  true
 false
 false
Run Code Online (Sandbox Code Playgroud)

通过广播infix ?\inTAB)运算符可以达到相同的结果:

julia> giant_list .? Ref(good_letters)
3-element BitArray{1}:
  true
 false
 false
Run Code Online (Sandbox Code Playgroud)

此外,in使用一个参数进行调用会创建一个Base.Fix2,以后可以通过广播的调用应用。但是,与仅定义函数相比,这似乎具有有限的好处。

julia> is_good1 = in(good_letters);
       is_good2(x) = x in good_letters;

julia> is_good1.(giant_list)
3-element BitArray{1}:
  true
 false
 false

julia> is_good2.(giant_list)
3-element BitArray{1}:
  true
 false
 false
Run Code Online (Sandbox Code Playgroud)

总而言之,使用.?a Ref可能会导致最短,最简洁的代码。