julia中的矢量化“in”功能?

问题描述 投票:7回答:4

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

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

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

isin = giant_list .in good_letters

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

dataframe vectorization julia
4个回答
7
投票

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

indexin(a, b)

返回包含b中最高索引的向量,该值为ab成员的每个值。只要a不是b的成员,输出向量就包含0。

因为你需要giant_list中每个元素的布尔值(而不是good_letters中的索引),你可以简单地做:

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

implementation of indexin非常简单,如果您不关心b中的指数,请指出如何优化此方法:

function vectorin(a, b)
    bset = Set(b)
    [i in bset for i in a]
end

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


4
投票

你可以使用in在Julia v0.6中很容易地矢量化unified broadcasting syntax

julia> in.(giant_list, (good_letters,))
3-element Array{Bool,1}:
  true
 false
 false

请注意使用单元素元组的scalarificationgood_letters。或者,您可以使用Scalar类型,例如StaticArrays.jl中引入的类型。

Julia v0.5支持相同的语法,但需要一个特殊的scalarificiation函数(或前面提到的Scalar类型):

scalar(x) = setindex!(Array{typeof(x)}(), x)

之后

julia> in.(giant_list, scalar(good_letters))
3-element Array{Bool,1}:
  true
 false
 false

4
投票

这个问题有一些现代(即Julia v1.0)解决方案:

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

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

通过广播中缀\inTAB)运算符可以实现相同的结果:

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

此外,使用一个参数调用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

总而言之,使用带有.∈Ref可能会导致最短,最干净的代码。


1
投票

findin()没有给你一个布尔掩码,但你可以很容易地使用它来为一个数组/ DataFrame配置另一个数组中包含的值:

julia> giant_list[findin(giant_list, good_letters)]
1-element Array{String,1}:
 "a"
© www.soinside.com 2019 - 2024. All rights reserved.