I’ve noticed that reduce
has an optional source
argument specifically to keep track of each block. With this, I now have the following wrapper:
function expand_grid(; kws...)
names, vals = keys(kws), values(kws)
return DataFrame(NamedTuple{names}(t) for t in Iterators.product(vals...))
end
function mymodel(;x = range(0, 10, length = 100), a = 1, b = 1, c = 2, fun = sin, kws...)
DataFrame(x = x, y = a .* sin.(b .* x) .+ c, z = a .* fun.(b .* x) .+ c)
end
function pmap_df(p, f, kws...; join=true)
tmp = map(f, eachrow(p), kws...)
all = reduce(vcat, tmp, source="id")
if !join
return all
end
p[!, :id] = 1:nrow(p)
return DataFrames.leftjoin(p, all, on=:id)
end
params = expand_grid(a=[0.1,0.2,0.3], b = [1,2,3], c = [0,0.5]);
pmap_df(params, p -> mymodel(;p..., fun=tanh))
That’s pretty close to what I was after; I’d still like to merge the map+reduce steps with mapreduce
, but I’m not sure how to pass extra arguments to reduce
. Any idea?