convert data type of any to float in matrix in Julia

Viewed 113

I have a matrix(rand2) of type "any", and I want to convert the type to float. I have following code.

for i in 1:size(rand2,1)
   rand2[i,:]=convert(Array{Float64,1}, rand2[i,:])
end

Such code will not change the data type. What‘s the issue here?

4 Answers

Use dot operator to vectorize over type conversion.

Suppose you have

julia> m = Matrix{Any}(rand(2,2))
2×2 Matrix{Any}:
 0.250737  0.0366769
 0.240182  0.883665

Than you could do

julia> Float64.(m)
2×2 Matrix{Float64}:
 0.250737  0.0366769
 0.240182  0.883665

or you could explicitly call vectorized convert:

julia> convert.(Float64, m)
2×2 Matrix{Float64}:
 0.250737  0.0366769
 0.240182  0.883665

Julia arrays, once created, cannot have their type changed; this is necessary for high performance. So, trying to change the type midway as you have tried won't work. You have to create a new array similar to the original one but with the new type.

You could do this:

m64 = similar(m, Float64)
m64 .= m

This will be 10X faster than direct conversion like Float64.(m).

In addition to Przemyslaw Szufel's answer, you can use the identity function, which narrows the element type of your matrix. Example:

# I use the example of Przemyslaw Szufel
julia> m = Matrix{Any}(rand(2,2))
2×2 Matrix{Any}:
 0.250737  0.0366769
 0.240182  0.883665

julia> identity.(m)
2×2 Matrix{Float64}:
 0.250737  0.0366769
 0.240182  0.883665

You can use Matrix to convert to Float64.

m = Matrix{Any}([1. 2.; 3. 4.])
#2×2 Matrix{Any}:
# 1.0  2.0
# 3.0  4.0

Matrix{Float64}(m)
#Array{Float64}(m) #Alternative
#2×2 Matrix{Float64}:
# 1.0  2.0
# 3.0  4.0

Also it's possible to use convert as shown already by @przemyslaw-szufel but without ..

convert(Matrix{Float64}, m)
#convert(Array{Float64}, m) #Alternative
#2×2 Matrix{Float64}:
# 1.0  2.0
# 3.0  4.0

The conversion by using similar shown by @AboAmmar need not to be done over an intermediate step.

similar(m, Float64) .= m
#2×2 Matrix{Float64}:
# 1.0  2.0
# 3.0  4.0

Benchmark

using BenchmarkTools

m = Matrix{Any}(rand(1000,1000))

@benchmark Float64.($m)
#BenchmarkTools.Trial: 32 samples with 1 evaluation.
# Range (min … max):  156.779 ms … 170.114 ms  ┊ GC (min … max): 0.00% … 0.00%
# Time  (median):     159.612 ms               ┊ GC (median):    0.00%
# Time  (mean ± σ):   161.097 ms ±   4.111 ms  ┊ GC (mean ± σ):  0.03% ± 0.07%
#
#  ▁ ▁   ▁▁ ▁  ▄ █                                                
#  █▁█▆▁▆██▁█▆▁█▆█▆▆▁▆▁▁▁▁▁▁▁▁▁▁▁▁▁▆▁▁▁▁▁▁▁▁▁▁▁▁▆▁▁▆▁▆▁▆▆▁▁▆▁▁▁▆ ▁
#  157 ms           Histogram: frequency by time          170 ms <
#
# Memory estimate: 7.63 MiB, allocs estimate: 2.

@benchmark convert.(Float64, $m)
#BenchmarkTools.Trial: 30 samples with 1 evaluation.
# Range (min … max):  168.258 ms … 177.510 ms  ┊ GC (min … max): 0.00% … 0.00%
# Time  (median):     170.444 ms               ┊ GC (median):    0.00%
# Time  (mean ± σ):   170.794 ms ±   1.996 ms  ┊ GC (mean ± σ):  0.05% ± 0.12%
#
#       █ ██     ▃      ▃  ▃                                      
#  ▇▁▇▇▁█▁██▁▁▇▁▇█▁▇▇▁▇▇█▇▇█▁▇▁▁▁▇▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▇▁▁▁▁▁▁▁▁▁▁▁▇ ▁
#  168 ms           Histogram: frequency by time          178 ms <
#
# Memory estimate: 7.63 MiB, allocs estimate: 13.

@benchmark identity.($m)
#BenchmarkTools.Trial: 58 samples with 1 evaluation.
# Range (min … max):  84.857 ms … 91.658 ms  ┊ GC (min … max): 0.00% … 0.00%
# Time  (median):     85.980 ms              ┊ GC (median):    0.00%
# Time  (mean ± σ):   86.873 ms ±  2.009 ms  ┊ GC (mean ± σ):  0.10% ± 0.24%
#
#  █    ▃▁▆  ▁    ▁                                             
#  █▄▇▇▄███▇▄█▇▁▄▁█▇▄▁▁▁▄▁▄▁▁▄▄▁▁▁▇▁▁▁▁▁▁▁▁▁▁▁▄▁▁▁▄▇▁▇▄▁▇▄▁▁▄▄ ▁
#  84.9 ms         Histogram: frequency by time        90.9 ms <
#
# Memory estimate: 7.63 MiB, allocs estimate: 12.

@benchmark begin
    m64 = similar($m, Float64)
    m64 .= $m
end
#BenchmarkTools.Trial: 289 samples with 1 evaluation.
# Range (min … max):  15.963 ms …  21.972 ms  ┊ GC (min … max): 0.00% … 3.92%
# Time  (median):     17.319 ms               ┊ GC (median):    0.00%
# Time  (mean ± σ):   17.332 ms ± 878.046 μs  ┊ GC (mean ± σ):  2.79% ± 2.83%
#
#   ▄ ▁ ▅                ▁▃▂▅▄█▂▂▁                               
#  ▇███▆██▃▃▄▃▄▁▁▁▁▁▁▁▄▄▇█████████▇▅▄▄▆▃▃▁▆▄▅▆▅██▇▄█▄▄▅▄▄▄▁▃▄▃▃ ▄
#  16 ms           Histogram: frequency by time           19 ms <
#
# Memory estimate: 22.88 MiB, allocs estimate: 999491.

@benchmark similar($m, Float64) .= $m
#BenchmarkTools.Trial: 299 samples with 1 evaluation.
# Range (min … max):  16.108 ms …  21.211 ms  ┊ GC (min … max): 0.00% #… 0.00%
# Time  (median):     16.795 ms               ┊ GC (median):    0.00%
# Time  (mean ± σ):   16.740 ms ± 500.870 μs  ┊ GC (mean ± σ):  1.81% #± 1.82%
#
#        ▂▃▄▆ ▃▁                   ▄▃ █                          
#  ▃▃▁▃▄█████▇██▅▇▄▆▆▆▃▅▃▃▁▅▃▄▃█▆████▅██▆█▆▅▆▅▅▃▃▃▄▃▃▁▃▁▄▁▁▁▁▁▃ ▃
#  16.1 ms         Histogram: frequency by time         17.6 ms <
#
# Memory estimate: 22.88 MiB, allocs estimate: 999491.

@benchmark Matrix{Float64}($m)
#BenchmarkTools.Trial: 282 samples with 1 evaluation.
# Range (min … max):  16.243 ms … 23.092 ms  ┊ GC (min … max): 0.00% … 7.39%
# Time  (median):     18.299 ms              ┊ GC (median):    4.62%
# Time  (mean ± σ):   17.745 ms ±  1.196 ms  ┊ GC (mean ± σ):  5.71% ± 5.45%
#
#    ▃▆▆█▂                                 ▃▄                   
#  ▃██████▄▆▃▄▄▅▁▃▃▄▃▃▃▁▁▁▁▁▁▁▁▁▁▁▃▃▄▅▆▇█▇███▇▇▇▆▆▃▃▃▃▁▃▁▄▃▃▁▃ ▃
#  16.2 ms         Histogram: frequency by time        19.9 ms <
#
# Memory estimate: 22.88 MiB, allocs estimate: 999491.

@benchmark convert(Matrix{Float64}, $m)
#BenchmarkTools.Trial: 301 samples with 1 evaluation.
# Range (min … max):  15.912 ms …  21.628 ms  ┊ GC (min … max): 0.00% #… 0.00%
# Time  (median):     16.719 ms               ┊ GC (median):    0.00%
# Time  (mean ± σ):   16.622 ms ± 576.159 μs  ┊ GC (mean ± σ):  2.43% #± 2.45%
#
#         ▆█                    ▁  ▃                             
#  ▂▁▂▄▅▄███▇▅▅▇▃▂▃▃▆▃▁▂▂▁▁▂▃▅▇▇█▇▅██▅▆▅▄▄▃▃▃▃▂▂▂▃▂▁▂▁▂▁▂▂▁▁▁▁▃ ▃
#  15.9 ms         Histogram: frequency by time         17.7 ms <
#
# Memory estimate: 22.88 MiB, allocs estimate: 999491.

Using similar, Matrix or convert are in this case about 5 times faster than using identity. and 10 times faster than convert. or Float64.. But they aren't memory efficient as identity., convert. and Float64. are and using in this case about 3 times more memory.

Related