我已经在几个地方在线看到了解决方案
a = [1 2 3; 4 5 Inf]
a[isinf(a)] = NaN
但这给我关于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>
有什么作用?
答案 0 :(得分:8)
作为附加评论。执行此操作的标准功能是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
对于大型阵列,它的性能要优于广播。
如果您确实需要速度,可以编写一个简单的函数,如下所示:
function inf2nan(x)
for i in eachindex(x)
@inbounds x[i] = ifelse(isinf(x[i]), NaN, x[i])
end
end
现在让我们简单地比较三个选项的性能:
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
答案 1 :(得分:3)
编辑:有关解决此问题的最佳方法,请参见@BogumilKaminski的出色回答。这个答案解决了一个更普遍的问题,为什么isinf
和相关函数不再在数组上起作用。
您遇到了一个更普遍的问题,即在v1.0之前的版本中,许多对数组起作用的功能不再在v1.0中的数组上起作用,因为您应该使用广播。 v1.0的正确解决方案是:
a[isinf.(a)] .= NaN
我实际上是在两个地方播音。首先,我们在数组isinf
上广播a
,但是我们也在NaN
上将RHS上的标量.=
广播到LHS数组上的所有索引位置。总的来说,点广播表示法非常灵活且性能卓越,是Julia的最新迭代中我最喜欢的功能之一。
答案 2 :(得分:0)
您正在将整个数组传递给isinf,它不适用于数组,适用于数字。试试这个:
[isinf(i) ? NaN : i for i in a]