# Transpose vector of vectors

**URL:** <https://discourse.julialang.org/t/transpose-vector-of-vectors/73313>\
**Category:** General Usage\
**Tags:** arrays, splitapplycombine\
**Created:** [December 19, 2021, 1:29am UTC](https://discourse.julialang.org/t/transpose-vector-of-vectors/73313 "2021-12-19T01:29:31Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![jzr](https://avatars.discourse-cdn.com/v4/letter/j/eb9ed0/32.png) [@jzr](https://discourse.julialang.org/u/jzr)\
**Post date:** [December 19, 2021, 1:29am UTC](https://discourse.julialang.org/t/transpose-vector-of-vectors/73313/1 "2021-12-19T01:29:31Z")

</div>

Is there a shorter way to write this?

```julia
n = 1000; m = 5000
xss = [repeat([j], n) for j in 1:m]

yss = [[] for _ in xss[1]]
for xs in xss
    for (x, ys) in zip(xs, yss)
        push!(ys, x)
    end
end

```

Maybe there is an Iterator in a package?

It is similar to

```julia
zip(xss...)

```

but `zip(...)` makes tuples instead of vectors so the compiler crashes for large `n,m`.

---

<div class="post-metadata">

**Author:** ![mohamed82008](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mohamed82008/32/18171_2.png) [@mohamed82008](https://discourse.julialang.org/u/mohamed82008)\
**Post date:** [December 19, 2021, 1:38am UTC](https://discourse.julialang.org/t/transpose-vector-of-vectors/73313/2 "2021-12-19T01:38:15Z")

</div>

```julia
yss = map(i -> getindex.(xss, i), 1:length(xss[1]))

```

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [December 19, 2021, 2:08am UTC](https://discourse.julialang.org/t/transpose-vector-of-vectors/73313/3 "2021-12-19T02:08:50Z")

</div>

Using TensorCast’s intuitive syntax:

```nohighlight
using TensorCast        
@cast yss[j][i] := xss[i][j]

```

---

<div class="post-metadata">

**Author:** ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)\
**Post date:** [December 19, 2021, 7:20am UTC](https://discourse.julialang.org/t/transpose-vector-of-vectors/73313/4 "2021-12-19T07:20:03Z")

</div>

```julia
using SplitApplyCombine

yss = invert(xss)

```

`invert` is exactly the function you are looking for:

> Return a new nested container by reversing the order of the nested container a, for example turning a dictionary of arrays into an array of dictionaries, such that a[i][j] === invert(a)[j][i].
> 
> Examples  
> ≡≡≡≡≡≡≡≡≡≡
> 
> julia\> invert([[1,2,3],[4,5,6]])  
> 3-element Array{Array{Int64,1},1}:  
> [1, 4]  
> [2, 5]  
> [3, 6]
> 
> julia\> invert((a = [1, 2, 3], b = [2.0, 4.0, 6.0]))  
> 3-element Array{NamedTuple{(:a, :b),Tuple{Int64,Float64}},1}:  
> (a = 1, b = 2.0)  
> (a = 2, b = 4.0)  
> (a = 3, b = 6.0)

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [December 19, 2021, 8:31am UTC](https://discourse.julialang.org/t/transpose-vector-of-vectors/73313/5 "2021-12-19T08:31:53Z")

</div>

Is that standard terminology? This looks for like a generalized transpose than invert.

---

<div class="post-metadata">

**Author:** ![jzr](https://avatars.discourse-cdn.com/v4/letter/j/eb9ed0/32.png) [@jzr](https://discourse.julialang.org/u/jzr)\
**Post date:** [December 19, 2021, 8:52am UTC](https://discourse.julialang.org/t/transpose-vector-of-vectors/73313/6 "2021-12-19T08:52:40Z")

</div>

This may be the function I’m looking for.

[https://github.com/JuliaLang/julia/issues/13942](https://github.com/JuliaLang/julia/issues/13942)

---

<div class="post-metadata">

**Author:** ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)\
**Post date:** [December 19, 2021, 9:17am UTC](https://discourse.julialang.org/t/transpose-vector-of-vectors/73313/7 "2021-12-19T09:17:48Z")

</div>

> [@DNF](#):
>
> Is that standard terminology? This looks for like a generalized transpose than invert.

Hard to say where to look for “standard terminology” in this case. Don’t know about the motivation for naming that function `invert` (@andyferris?), I’m just a happy user (: Is there is any truly obvious name anyway?

---

<div class="post-metadata">

**Author:** ![cjdoris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cjdoris/32/213133_2.png) [@cjdoris](https://discourse.julialang.org/u/cjdoris)\
**Post date:** [December 19, 2021, 9:37am UTC](https://discourse.julialang.org/t/transpose-vector-of-vectors/73313/9 "2021-12-19T09:37:12Z")

</div>

I’d’ve called it `insideout` 🙂

---

<div class="post-metadata">

**Author:** ![Seif\_Shebl](https://avatars.discourse-cdn.com/v4/letter/s/eada6e/32.png) [@Seif\_Shebl](https://discourse.julialang.org/u/Seif_Shebl)\
**Post date:** [December 19, 2021, 12:36pm UTC](https://discourse.julialang.org/t/transpose-vector-of-vectors/73313/10 "2021-12-19T12:36:52Z")

</div>

Or simply a comprehension?

```julia
yss = [[xss[j][i] for j=1:m] for i=1:n];

```

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [December 19, 2021, 12:37pm UTC](https://discourse.julialang.org/t/transpose-vector-of-vectors/73313/11 "2021-12-19T12:37:51Z")

</div>

@aplavin, would you mind benchmarking `invert()` for OP’s data?

I see it about ~400x slower than TensorCast.  
_(Win11, Julia 1.7, SplitApplyCombine v1.2.0, TensorCast v0.4.3)_

> **versioninfo()**
>
> julia\> versioninfo()  
> Julia Version 1.7.0  
> Commit 3bf9d17731 (2021-11-30 12:12 UTC)  
> Platform Info:  
> OS: Windows (x86\_64-w64-mingw32)  
> CPU: Intel(R) Core™ i7-1065G7 CPU @ 1.30GHz  
> WORD\_SIZE: 64  
> LIBM: libopenlibm  
> LLVM: libLLVM-12.0.1 (ORCJIT, icelake-client)  
> Environment:  
> JULIA\_PKG\_USE\_CLI\_GIT = true  
> JULIA\_STACKFRAME\_FUNCTION\_COLOR = blue  
> JULIA\_WARN\_COLOR = cyan  
> JULIA\_EDITOR = code.cmd -g  
> JULIA\_NUM\_THREADS = 8

```julia
using TensorCast
function trans_tc(xss)
    @cast yss[j][i] := xss[i][j];
    return yss
end

using SplitApplyCombine
trans_sap(xss) = invert(xss)

n = 1000; m = 5000
xss = [repeat([j], n) for j in 1:m];

trans_tc(xss) == trans_sap(xss) # true

using BenchmarkTools
@btime trans_tc($xss); # 33.3 μs (5 allocations: 39 KiB)
@btime trans_sap($xss); # 13.5 ms (2001 allocations: 38.2 MiB)

```

---

<div class="post-metadata">

**Author:** ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)\
**Post date:** [December 19, 2021, 12:53pm UTC](https://discourse.julialang.org/t/transpose-vector-of-vectors/73313/12 "2021-12-19T12:53:31Z")

</div>

Yes, I see similar results. That’s the difference between lazy (`@cast`) and eager (`invert`) operations.

I guess `SplitApplyCombine` could get a lazy `invertview` function if someone is interested and makes a PR. For now, there are `splitdimsview` + `combinedimsview`:

```julia
julia> splitdimsview(combinedimsview(xss), 1) == invert(xss)
true

julia> @btime splitdimsview(combinedimsview($xss), 1)
1.695 ns (0 allocations: 0 bytes)

```

Another 20000 times faster than `@cast` (:

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [December 19, 2021, 1:26pm UTC](https://discourse.julialang.org/t/transpose-vector-of-vectors/73313/13 "2021-12-19T13:26:58Z")

</div>

@aplavin, I can’t help but say: this is awesome! Thank you.
