Efficient way to transform Array{Union{Missing,Float64}} to Array{Float64}?

#1

there is a way to transform an array x1 of Union{Missing,Float64} to an Array x2 of Float64 without allocating a new array? .x1 doesn’t containg missing values. an example:

x1 = Array{Union{Missing,Float64}}(undef,3)
for i = 1:3 
x1[i]=i
end

julia> x1
3-element Array{Union{Missing, Float64},1}:
 1.0
 2.0
 3.0

you can do this by allocating a new array, but there is another way?

0 Likes

#2

identity.(x) should be good. Or map(identity, x).

Or

using Missings
disallowmissing(x)
1 Like

#3

AFAIK all solutions will allocate, unless you rely on internals (but don’t do that).

3 Likes

#4

There’s an open issue for this but currently no “public” API for it:

3 Likes

#5

a related question, how do i detect that said vector has a missing value?, I’m using in(true,(ismissing.(x)))==true but i’m sure there is a simpler way

0 Likes

#6

any(ismissing, x) will do it.

3 Likes

#7
Missings.disallowmissing(x)
convert(Vector{Float64}, x)
1 Like

#8
julia> a = Union{Float64,Missing}[1.1, 2.2]
2-element Array{Union{Missing, Float64},1}:
 1.1
 2.2

julia> using MappedArrays

julia> b = of_eltype(Float64, a)
2-element mappedarray(x->(MappedArrays.convert)($(Expr(:static_parameter, 1)), x), y->(MappedArrays.convert)($(Expr(:static_parameter, 1)), y), ::Array{Union{Missing, Float64},1}) with eltype Float64:
 1.1
 2.2

julia> eltype(b)
Float64

You can easily convince yourself that there is no copy of a made:

julia> b[1] = 200
200

julia> a
2-element Array{Union{Missing, Float64},1}:
 200.0
   2.2
1 Like

#9

Strictly speaking, there is no transformation either but a view, and the result is not an Array{Float64} (that was asked for) but something else.

That said, I think this may be the best solution under some circumstances, as it can be very efficient. So perhaps the original question should have been not how to get an Array{Floa64}, but an array with Float64 eltype.

1 Like