I’d like to store a table as a mixed-type numeric array - just ints and floats.
If I use [brackets] to initialize a vector of numeric values, Julia promotes the ints to floats and returns an array of floats. If I include a non-numeric type (e.g. string) as the last value and then pop! the vector (or subset it to a the index range of numeric-only values), it preserves the remaining numbers in an Any-type vector. Is there a way to do this without including then removing a non-numeric value?
v = [1.5,1,"foo"]; pop!(v); # v is now a length-2 Vector{Any}
v = [1.5,1]; # v here is a Vector{Float64}
Apologies in advance if this has already been answered. I did do a search before posting.
You pre-pend the eltype:
Any[5,6]
gives an Array{Any,1}
. To just store ints and floats you could do
Union{Int,Float64}[5, 6, 9.0]
or maybe just Real[1, 2.0]
.
Edit: note that performance maybe worse with heterogeneous arrays.
4 Likes
Thanks for the quick answer, mauro3!
I wasn’t aware of the T[]
syntax for arrays.
1 Like
Something to note: there’s a big jump in performance for functions acting on small union types between Julia 0.6 and 0.7, although operations on arrays of Real
s don’t seem to have changed:
# v0.6.2
using BenchmarkTools
u = Union{Int64, Float64}[rand() < 0.5 ? 1 : 1.0 for i = 1:1000]
v = Real[rand() < 0.5 ? 1 : 1.0 for i = 1:1000]
@btime sum($u) # -> 42.516 μs (3466 allocations: 54.16 KiB)
@btime sum($v) # -> 27.661 μs (1000 allocations: 15.63 KiB)
vs.
# v0.7.0-DEV.5075
using BenchmarkTools
u = Union{Int64, Float64}[rand() < 0.5 ? 1 : 1.0 for i = 1:1000]
v = Real[rand() < 0.5 ? 1 : 1.0 for i = 1:1000]
@btime sum($u) # -> 9.788 μs (0 allocations: 0 bytes)
@btime sum($v) # -> 25.940 μs (999 allocations: 15.61 KiB)
3 Likes
Yep, Real
s are not a small union, anything but as this post nicely describes: Type stability for returning abstract types - #2 by mbauman
1 Like