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

Julia 如何将数组中的小值归零?,julia,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 功能稀疏(a,eps) 我在印地安语(a) 如果abs(a[i])

是否有一种将数组中的小值归零的通用方法

“小”是指绝对值小于某个阈值的元素,如
10.0^-5

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

function sparsify(a, eps)
    for i in eachindex(a)
        if abs(a[i]) < eps
            a[i] = 0
        end 
    end
end
功能稀疏(a,eps)
我在印地安语(a)
如果abs(a[i])
我最终得到了一个向量化方法,它要短得多

sparsify(x, eps) = abs(x) < eps ? 0.0 : x
@vectorize_2arg Float64 sparsify
sparsify(x,eps)=abs(x)
为什么不应用掩码和元素小于运算符

>>> x = rand(Float32, 100)
>>> eps = 0.5
>>> x[abs(x) .< eps] = 0
您还可以将
0
替换为
0(eltype(x))
,以确保其类型与
x
相同

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

免责声明(2019):下面的答案已严重过时,并引用了Julia(abs(x)abs(x)time_sparse(10^8,0.1)的旧版本 0.122510秒 1.078589秒(73.25 k分配:778.590 MB,gc时间的5.42%) 0.558914秒(2次分配:762.940 MB) 0.688640秒(5次分配:762.940 MB) 0.243921秒
循环(最快的)和简单的矢量化循环之间有很大的区别

编辑:
zerofy3!
=>
zerofy3
,因为它没有就位。

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

x[abs.(x) .< eps(eltype(x))] .= zero(eltype(x))
x[abs.(x)。
这个掩码很有趣。问题不在于
x.
而是
abs(x)。
,这似乎有效。你能相应地更新你的解决方案吗?顺便问一下,感叹号是修改其参数的函数的约定吗?@Valéry编辑了答案以显示
abs(x)
,没有注意到这个细节,谢谢!是的,要注意函数在内部修改参数。这是完全可选的,github上有几篇文章建议将来可能会删除或更改它,但现在它已被广泛采用(所有julia核心函数和大多数包都遵循它)。我尝试用julia 1.1.1测试上述内容,并发现了一些差异。在for循环中,它应该是enumerate(x)
中的(I,val)的
,因为索引是首先提供的。第二个工作原理如下:
zerofy2!(x,vmin)=(x[abs.(x)。
。我无法使
zerofy3
zerofy4
zerofy4!
正常工作。不过,计时似乎仍然相同,第一个运行速度比第二个快。
(0.876196比0.977687)
此答案引用了Julia的一个旧版本。您是对的,我使用的
枚举
错误,但整个答案已严重过时。例如,
@vectorize2Arg
宏已不存在,现在有更好的方法来执行此操作(例如,只需编写
x.=0
,或使用
填充!
)我将在顶部添加一个免责声明。在Julia 1.0中,没有必要显式调用
@vectorize_2arg
。相反,在函数调用后添加一个点。例如,调用
稀疏。([a,b,c],eps)
function zerofy!(x, vmin)
    for (i, val) 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
x[abs.(x) .< eps(eltype(x))] .= zero(eltype(x))