如何将数组中的小值归零?

时间:2016-05-08 15:10:06

标签: julia

是否存在将数组中的小值归零的通用方法?

小"小"我的意思是绝对值小于某个阈值的元素,如10.0^-5

编辑:现在,我循环使用eachindex

function sparsify(a, eps)
    for i in eachindex(a)
        if abs(a[i]) < eps
            a[i] = 0
        end 
    end
end

4 个答案:

答案 0 :(得分:5)

为什么不直接应用掩码和元素 运算符?

>>> x = rand(Float32, 100)
>>> eps = 0.5
>>> x[abs(x) .< eps] = 0

或作为函数(注意函数修改向量x inplace):

>>> sparsify!(x, eps) = x[abs(x) .< eps] = 0;

您也可以将0替换为zero(eltype(x)),以确保其类型与x相同。

x .< eps创建的临时布尔掩码会将x的每个元素与eps进行比较。然后,满足该条件的每个元素都将设置为0。

答案 1 :(得分:1)

我最终得到了一个矢量化方法,这个方法要短得多。

sparsify(x, eps) = abs(x) < eps ? 0.0 : x
@vectorize_2arg Float64 sparsify

答案 2 :(得分:1)

选择何种方法取决于您的需求。如果你只需要一个简单的单行,那么矢量化版本就可以了。但是如果你想要最佳性能,循环将更好地为你服务。

以下是一些通过性能进行比较的替代方案。请记住,function zerofy!(x, vmin) for (val, i) in enumerate(x) if abs(val) < vmin x[i] = zero(eltype(x)) end end end zerofy2!(x, vmin) = ( x[abs(x) .< vmin] = zero(eltype(x)) ) zerofy3(x, eps) = abs(x) < eps ? 0.0 : x @vectorize_2arg Float64 zerofy3! zerofy4(y, vmin) = map(x -> abs(x)<vmin ? zero(x) : x, y) zerofy4!(y, vmin) = map!(x -> abs(x)<vmin ? zero(x) : x, y) function time_zerofy(n, vmin) x1 = rand(n) x2, x3, x4, x5 = copy(x1), copy(x1), copy(x1), copy(x1) @time zerofy!(x1, vmin) @time zerofy2!(x2, vmin) @time zerofy3(x3, vmin) @time zerofy4(x4, vmin) @time zerofy4!(x5, vmin) return nothing end julia> time_sparse(10^8, 0.1) 0.122510 seconds 1.078589 seconds (73.25 k allocations: 778.590 MB, 5.42% gc time) 0.558914 seconds (2 allocations: 762.940 MB) 0.688640 seconds (5 allocations: 762.940 MB) 0.243921 seconds 版本0.4很慢。这里的时间安排是0.5版本。

zerofy3!

循环(最快)和天真矢量化循环之间存在很大差异。

修改:zerofy3 =&gt; Ax2+VAx*t1=Bx1+VBx*t1 t1=(Bx1-Ax2)/(VAx-VBx) t2=(Bx2-Ax1)/(VAx-VBx) 因为它不在原地。

答案 3 :(得分:0)

要完成Imanol Luengo的答案,并将其扩展到多个维度,

x[abs.(x) .< eps(eltype(x))] .= zero(eltype(x))