如何根据条件简单地选择数组的子集?我知道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]
如何根据条件简单地选择数组的子集?我知道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)]
更快。
x[x%2.==0]
呢?这里的 find
是不必要且缓慢的。 - 张实唯@time y2 …
之所以更快,是因为它没有执行你认为它正在执行的操作。y2
是空的!你漏掉了 .==
中的 .
。修复这个问题,你会发现调用 find()
的确更慢。 - mbauman另一个更新版本:
v[v .% 2 .== 0]
可能,对于Julia的新版本,需要在%
和==
之前添加广播点。
find
性能的 相关问题。根据您的设计考虑,您可以编写自己的有效程序来处理x % 2 == 0
,或者只需使用 Julia 的易于阅读的filter
或find
函数,就像下面的人们所描述的那样。 - Kevin L. Keys==
以这种方式进行索引,而不是.==
。我不确定该选择哪个答案,它们在不同方面都是正确的,并且非常有用。 - David Parks