Генерация именованных кортежей массивов на карте функции, которая производит именованные кортежи - PullRequest
0 голосов
/ 25 сентября 2018

Возьмем, к примеру, функцию, которая генерирует именованные кортежи

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 голосов
/ 26 сентября 2018

Как насчет прямого построения Y с помощью конструктора NamedTuple {N, T}?

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}}}
0 голосов
/ 25 сентября 2018

Кристоффер Карлссон показал мне, что StructArrays.jl дает хороший ответ, если причиной получения именованного кортежа массивов является создание таблицы DataFrame или JuliaDB.Используя его намеки, я придумал:

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)
...