如何根据Julia中的条件选择数组的子集

时间:2016-06-04 03:13:14

标签: julia

如何根据条件简单地选择数组的子集?我知道Julia不使用矢量化,但是必须有一种简单的方法来执行以下操作,而不需要看起来很丑陋的多行for循环

julia> map([1,2,3,4]) do x
       return (x%2==0)?x:nothing
       end
4-element Array{Any,1}:
  nothing
 2
  nothing
 4

期望的输出:

[2, 4]

观察输出:

[nothing, 2, nothing, 4]

3 个答案:

答案 0 :(得分:10)

您正在寻找filter http://docs.julialang.org/en/release-0.4/stdlib/collections/#Base.filter

这是一个例子 filter(x->x%2==0,[1,2,3,5]) #anwers with [2]

答案 1 :(得分:8)

有元素操作符(以“。”开头):

julia> [1,2,3,4] % 2 .== 0
4-element BitArray{1}:
 false
  true
 false
  true

julia> x = [1,2,3,4]
4-element Array{Int64,1}:
 1
 2
 3
 4

julia> x % 2 .== 0
4-element BitArray{1}:
 false
  true
 false
  true

julia> x[x % 2 .== 0]
2-element Array{Int64,1}:
 2
 4

julia> x .% 2
4-element Array{Int64,1}:
 1
 0
 1
 0

答案 2 :(得分:6)

您可以使用find()函数(或.==语法)来完成此任务。 E.g:

julia> x = collect(1:4)
4-element Array{Int64,1}:
 1
 2
 3
 4    

julia> y = x[find(x%2.==0)]
2-element Array{Int64,1}:
 2
 4

julia> y = x[x%2.==0]  ## more concise and slightly quicker
2-element Array{Int64,1}:
 2
 4

注意元素操作的.==语法。另请注意,find()返回与条件匹配的索引。在这种情况下,匹配条件的索引与匹配条件的数组元素相同。但是对于更一般的情况,我们希望将find()函数放在括号中,以表示我们正在使用它来从原始数组x中选择索引。

更新: @Lutfullah Tomak关于filter()功能的好点。我相信虽然find()可以更快,更有效。 (虽然我知道匿名函数应该在0.5版本中变得更好所以这可能会改变吗?)至少在我的试验中,我得到了:

x = collect(1:100000000);
@time y1 = filter(x->x%2==0,x);  
# 9.526485 seconds (100.00 M allocations: 1.554 GB, 2.76% gc time)    

@time y2 = x[find(x%2.==0)]; 
# 3.187476 seconds (48.85 k allocations: 1.504 GB, 4.89% gc time)

@time y3 = x[x%2.==0];
# 2.570451 seconds (57.98 k allocations: 1.131 GB, 4.17% gc time)    

更新2:对此帖子的评论中的好点x[x%2.==0]x[find(x%2.==0)]快。