ARM
ARM

Reputation: 1550

Why does map throw away type information when operating on DataArrays?

I'm trying to understand why this is happening even given the limitations of DataArrays. Suppose you want to map over a DataArray of Int64s:

da = DataArray([1,2,3,4])
println(typeof(da))
println(typeof(map(a -> a^2, da))) # Returns an int for this input
println(typeof(map(a -> int(a^2), da))) # Cast the piecewise result to int
println(typeof(int(map(a -> a^2, da)))) # Cast the output DataArray{Any,1} to int

which results in

DataArray{Int64,1}
DataArray{Any,1}
DataArray{Any,1}
Array{Int64,1}

For an array, a = [1,2,3,4], map(a -> a^2, da) returns an Array of Int64s as expected. What is it about map and/or DataArrays that's causing type information to be lost here? Is there any solution to preserve type information when you're working with a type which doesn't have a constructor that converts DataArray{Any,1} to DataArray{ThatType,1}, like Dates.DateTime?

Edit: convert works fine to make a DataArray{Any,1} a DataArray{ThatType,1} (well at least for DateTime).

Upvotes: 2

Views: 67

Answers (1)

user5221125
user5221125

Reputation:

@which map(a -> a^2, da::DataArray{Int64, 1})  
map(f::Function,dv::DataArray{T,1}) at /home/omer/.julia/v0.3/DataArrays/src/datavector.jl:114  

Checking the source;
https://github.com/JuliaStats/DataArrays.jl/blob/master/src/datavector.jl

# TODO: should this be an AbstractDataVector, so it works with PDV's?
function Base.map(f::Function, dv::DataVector)
    n = length(dv)
    res = DataArray(Any, n)
    for i in 1:n
        res[i] = f(dv[i])
    end
    return res
end

It's creating the type DataArray{Any,1} to return.

res = DataArray(Any, n) 

You can check the answer given by James Fairbanks (1 Apr 04:12 2015)
http://blog.gmane.org/gmane.comp.lang.julia.user/month=20150401

Upvotes: 2

Related Questions