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

时间:2018-09-25 17:05:53

标签: julia namedtuple

例如,一个生成命名元组的函数

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是如何通过知道这些名字而生成的?

2 个答案:

答案 0 :(得分:1)

如何使用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}}}

答案 1 :(得分:0)

Kristoffer Carlsson告诉我,如果获取数组命名元组的原因是建立DataFrame或JuliaDB表,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)