How to interleave arrays in julia
Asked Answered
G

5

9

Is it possible to interleave two arrays in julia?

For example if a=[1:10] and b=[11:20] I want to be able to return

20-element Array{Int64,1}:
  1
  11
  2
  12
  3
  13
  4
  14
  .
  .
  .

Somewhat similar to what ruby can do Merge and interleave two arrays in Ruby

Gridley answered 6/6, 2014 at 13:25 Comment(0)
G
5

Figured it out!

reshape([a b]',20,1)

and for something more general:

reshape([a b].',size(a,1)+size(b,1),1)

we can use a hack to get vectors instead of 1D arrays:

reshape([a b].',size(a,1)+size(b,1),1)[:]
Gridley answered 6/6, 2014 at 13:32 Comment(2)
The difference may not be important for your use case, but those will produce 20x1 Array{Int64,2} objects, not 10-element Array{Int64,1} objects.Lentamente
Ah yes thanks for pointing that out. I edited the answer using the hack specified here #23958234Gridley
P
9

There is a straightforward way to do this without needing to use the reshape() function. In particular, we can just bind the vectors into a matrix and then use [:] on the transpose of that matrix. For example:

    julia> a = 1:10
    julia> b = 11:20
    julia> [a b]'[:]
    20-element Array{Int64,1}:
     1
    11
     2
    12
     3
    13
     .
     .
     .
    20

Taking the transpose of the matrix [a b] gives us a 2-by-10 matrix, and then [:] returns all of its elements in the form of a vector. The reason [:] works so nicely for us is because Julia uses column-major ordering.

Plumber answered 18/3, 2016 at 14:59 Comment(1)
For tuple arrays this fails, but you can use permutedims(tuples_2D)[:] instead of tuples_2D'[:]Sessile
G
5

Figured it out!

reshape([a b]',20,1)

and for something more general:

reshape([a b].',size(a,1)+size(b,1),1)

we can use a hack to get vectors instead of 1D arrays:

reshape([a b].',size(a,1)+size(b,1),1)[:]
Gridley answered 6/6, 2014 at 13:32 Comment(2)
The difference may not be important for your use case, but those will produce 20x1 Array{Int64,2} objects, not 10-element Array{Int64,1} objects.Lentamente
Ah yes thanks for pointing that out. I edited the answer using the hack specified here #23958234Gridley
P
4

You could just use

reshape([a b].', length(a)+length(b))

to get a vector.

Propulsion answered 6/6, 2014 at 18:49 Comment(1)
thanks, noted. I guess the hack is more usefull when you are note explicitly using reshape.Gridley
P
2
julia> @benchmark collect(Iterators.flatten(zip(a,b))) setup = begin a=rand(100); b=rand(100) end
BenchmarkTools.Trial: 10000 samples with 714 evaluations.
 Range (min … max):  190.895 ns …   1.548 μs  ┊ GC (min … max): 0.00% … 65.85%
 Time  (median):     238.843 ns               ┊ GC (median):    0.00%
 Time  (mean ± σ):   265.428 ns ± 148.757 ns  ┊ GC (mean ± σ):  8.40% ± 11.75%

  ▅▅██▅▃▂▂▁                                                  ▁▁ ▂
  ██████████▇█▇▇▅▄▄▃▁▁▁▃▄█▅▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▃▁▁▁▁▃▃▁▁▁▁▁▃▁▃▄▆▇███ █
  191 ns        Histogram: log(frequency) by time       1.11 μs <

 Memory estimate: 1.77 KiB, allocs estimate: 1.

it seems that

collect(Iterators.flatten(zip(a,b)))

is much faster

Pithecanthropus answered 7/6, 2022 at 2:41 Comment(0)
M
1

For completeness, expanding @bdeonovic's solution to 2 dimensional arrays.

julia>  a
2×2 Array{Int64,2}:
 1  2
 3  4

julia> b
2×2 Array{Int64,2}:
 6  7
 8  9

Interweaving rows:

julia> reshape([a[:] b[:]]', 4, 2)
4×2 Array{Int64,2}:
 1  2
 6  7
 3  4
 8  9

Interweaving columns:

julia> reshape( [a' b']', 2, 4 )
2×4 Array{Int64,2}:
 1  6  2  7
 3  8  4  9

Interweaving arrays (stacking/vcatting):

julia> reshape([a' b']', 4, 2)
4×2 Array{Int64,2}:
 1  2
 3  4
 6  7
 8  9
Michaelson answered 11/7, 2017 at 0:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.