Hello, I have an exciting problem. Consider type Block
and rawData
Matrix.
struct Block
name::String
data::Vector{Float64}
end
headers = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"]
rawData = rand(8700, 10)
dataRanges = Vector{UnitRange}([1:400, 500:8000])
Now we want to transform Matrix into Vector{Block}
with using data ranges. My naive solution is:
function fNaive(rawData::Matrix{Float64}, dataRanges::Vector{UnitRange})
db = map(1:cols(rawData)) do i
map(r -> Block(headers[i], view(rawData, r, i)), dataRanges)
end
vcat(db...)
end
How to get the most effective solution for Vector{Block}
, any solution?
Thanks
For better imagination, one block is a one-color of the Matrix.
1 Like
I get the impression that this is a very effective solution. I’ve replaced the nested function map
with comprehension, which gives a little better results.
Ou, I forgot to add cols
function, but that could be clearly.
cols(X::Array) = size(X, 2)
Depends on what you mean by “effective”. It is probably not the most efficient solution because of the extra arrays and copies via vcat
. I would just tend to do something like:
v = Block[]
for i in 1:size(rawData,2), r in dataRanges
push!(v, Block(headers[i], view(rawData, r, i)))
end
return v
which is both shorter and more efficient.
(Coming from other languages, people are often afraid to write loops. Sometimes explicit loops are the clearest code, and they are often the most efficient too!)
2 Likes