Hello,
I was wondering if there is a simple way to convert a NamedTuple with a mix of vectors and matrices, such as,
np = (x = [1 1; 1 2; 2 1; 2 2], y = [1,2,3,4])
to a DataFrame, such as
df = DataFrame(x1 = [1,1,2,2], x2=[1,2,1,2], y=[1,2,3,4])
4×3 DataFrame
Row │ x1 x2 y
│ Int64 Int64 Int64
─────┼─────────────────────
1 │ 1 1 1
2 │ 1 2 2
3 │ 2 1 3
4 │ 2 2 4
Thank you.
FWIW:
DataFrame(reduce(vcat, eachcol(x) for x in np), [:x1, :x2, :y])
1 Like
hcat(DataFrame(np.x,:auto),DataFrame(;np.y))
DataFrame(hcat(np.x,np.y),:auto)
DataFrame(hcat(np...),:auto)
2 Likes
sijo
March 9, 2024, 8:46pm
4
DataFrame(["$k$i" => c for (k,v) in pairs(np) for (i, c) in pairs(eachcol(v))])
2 Likes
Thank you everyone for the suggestions. I think the one by sijo is the closest to what I am aiming for. I think the only drawback is the extra “1” added to y. I’ll see if I can find a way to add numbers to columns of matrices.
You could tweak it further:
DataFrame([(k == :x ? "$k$i" : "$k") => c for (k,v) in pairs(np) for (i, c) in pairs(eachcol(v))])
I assume you have a more general situation like the following.
You could adapt the script like this
julia> np = (x = [1 1; 1 2; 2 1; 2 2],z = [1 1; 1 2; 2 1; 2 2], y = [1,2,3,4])
(x = [1 1; 1 2; 2 1; 2 2], z = [1 1; 1 2; 2 1; 2 2], y = [1, 2, 3, 4])
julia> DataFrame([v isa Matrix ? "$k$i" => c : "$k" => c for (k,v) in pairs(np) for (i, c) in pairs(eachcol(v))])
4×5 DataFrame
Row │ x1 x2 z1 z2 y
│ Int64 Int64 Int64 Int64 Int64
─────┼───────────────────────────────────
1 │ 1 1 1 1 1
2 │ 1 2 1 2 2
3 │ 2 1 2 1 3
4 │ 2 2 2 2 4
julia> DataFrame(["$k" => c for (k,v) in pairs(np) for c in eachcol(v)],makeunique=true)
4×5 DataFrame
Row │ x x_1 z z_1 y
│ Int64 Int64 Int64 Int64 Int64
─────┼───────────────────────────────────
1 │ 1 1 1 1 1
2 │ 1 2 1 2 2
3 │ 2 1 2 1 3
4 │ 2 2 2 2 4
2 Likes
Dan
March 9, 2024, 11:09pm
8
Another method to tweak rafael’s answer which doesn’t add 1
to y
:
DataFrame(["$k"*"$i"^(v!=c)=>c for (k,v) in pairs(np) for
(i,c) in pairs(eachcol(v))])
3 Likes