在生成命名元组的函数的映射上生成命名的数组元组

Generating named tuples of arrays on a map of a function that produces named tuples

以生成命名元组的函数为例

f(t) = (a=t,b=2t)

我可以轻松创建命名元组数组

ts = 0.0:0.01:1.0
X = f.(ts)

但是,我想要类似的数组结构格式:

Y = (a=collect(ts),b=collect(2ts))

你如何有效地生成这个?我很接近。如果我提前知道名字,我可以这样写:

Y = (a=Vector{Float64}(undef,length(t)),b=Vector{Float64}(undef,length(t)))
for (i,t) in enumerate(ts)
  val = f(t)
  for (j,x) in enumerate(Y)
    Y[j][i] = val[j]
  end
end
Y

但是,使用正确的名称生成 Y 是个问题。我可以得到像

这样的名字
template = f(first(ts))
syms = fieldnames(typeof(template))

但是 Y 是如何通过知道这些名字产生的?

Kristoffer Carlsson 告诉我,如果获取命名数组元组的原因是构建 DataFrame 或 JuliaDB table,StructArrays.jl 提供了一个很好的答案。根据他的提示,我想到了:

template = f(first(ts))
Y = [Vector{Float64}(undef,length(ts)) for i in 1:length(template)]
for (i,t) in enumerate(ts)
  val = f(t)
  for (j,x) in enumerate(Y)
    Y[j][i] = val[j]
  end
end
_Y = StructArray{typeof(template)}(Y...)

using DataFrames
@time DataFrame(_Y)

使用 NamedTuple{N, T} 构造函数直接构造 Y 怎么样?

julia> f(t) = (a=t,b=2t)
f (generic function with 1 method)

julia> ts = 0.0:0.01:1.0
0.0:0.01:1.0

julia> X = f.(ts);

julia> p(template::NamedTuple{N}, value::T) where {N, T} = NamedTuple{N, T}(value)
p (generic function with 1 method)

julia> p(X[1], (rand(4), rand(4)))
(a = [0.879929, 0.985692, 0.815627, 0.379551], b = [0.289546, 0.687192, 0.228028, 0.545847])

julia> typeof(ans)
NamedTuple{(:a, :b),Tuple{Array{Float64,1},Array{Float64,1}}}