如何根据条件简单地选择数组的子集?我知道 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]
您正在寻找
filter
http://docs.julialang.org/en/release-0.4/stdlib/collections/#Base.filter
这里是一个
filter(x->x%2==0,[1,2,3,5])
返回 [2]
的示例。
有逐元素运算符(以“.”开头):
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
您可以使用
find()
函数(或 .==
语法)来完成此操作。 例如:
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)]
更快。
另一个更新版本:
v[v .% 2 .== 0]
可能,对于较新版本的 Julia,需要在
%
和 ==
之前添加广播点