如何在Julia 1.0中用数组中的NaN替换Inf值?

nfe*_*and 2 julia

我在网上看过一些解决方案

 a = [1 2 3; 4 5 Inf]
 a[isinf(a)] = NaN
Run Code Online (Sandbox Code Playgroud)

但这给了我一个关于Julia 1.0.1的错误:

 ERROR: MethodError: no method matching isinf(::Array{Float64,2})
 Closest candidates are:
   isinf(::BigFloat) at mpfr.jl:851
   isinf(::Missing) at missing.jl:79
   isinf(::ForwardDiff.Dual) at <path on my local machine>
Run Code Online (Sandbox Code Playgroud)

是什么赋予了?

Bog*_*ski 9

作为补充评论.执行此操作的标准功能是replace!.你可以像这样使用它:

julia>  a = [1 2 3; 4 5 Inf]
2×3 Array{Float64,2}:
 1.0  2.0    3.0
 4.0  5.0  Inf

julia> replace!(a, Inf=>NaN)
2×3 Array{Float64,2}:
 1.0  2.0    3.0
 4.0  5.0  NaN
Run Code Online (Sandbox Code Playgroud)

它的性能优于大型阵列的广播.

如果你真的需要速度,你可以编写一个这样的简单函数:

function inf2nan(x)
    for i in eachindex(x)
        @inbounds x[i] = ifelse(isinf(x[i]), NaN, x[i])
    end
end
Run Code Online (Sandbox Code Playgroud)

现在让我们简单地比较三个选项的性能:

julia> function bench()
           x = fill(Inf, 10^8)
           @time x[isinf.(x)] .= NaN
           x = fill(Inf, 10^8)
           @time replace!(x, Inf=>NaN)
           x = fill(Inf, 10^8)
           @time inf2nan(x)
       end
bench (generic function with 1 method)

julia> bench()
  0.980434 seconds (9 allocations: 774.865 MiB, 0.16% gc time)
  0.183578 seconds
  0.109929 seconds

julia> bench()
  0.971408 seconds (9 allocations: 774.865 MiB, 0.03% gc time)
  0.184163 seconds
  0.102161 seconds
Run Code Online (Sandbox Code Playgroud)

  • 是的,在朱莉娅 - 相反做例如R - 如果你需要表现,你通常会想避免分配二进制矢量来执行子集.在这种特殊情况下,循环比`replace !`更快,因为我们可以使用`ifelse`来避免循环中的分支,因为我们执行的操作很简单,并且`@inbounds`编译器可以显着优化其执行时间. (2认同)