Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Slice array of arrays in Julia

Tags:

arrays

julia

In Julia, I have an array of arrays, say:

    arr = Array(Array{Float64,1},3)
    for i = 1:3
        arr[i] = [i,-i]
    end

Now:

   arr[:][1]
   2-element Array{Float64,1}:
      1.0
     -1.0

and

   arr[1][:]
    2-element Array{Float64,1}:
     1.0
    -1.0

It seems the only way to get the first 'column' is by comprehension

    pluses = [arr[i][1] for i=1:length(arr)]
    3-element Array{Any,1}:
     1.0
     2.0
     3.0

Is that indeed the only way? Do I lose in speed by running a for loop instead of some 'vectorized' version, or does it not matter in Julia due to different compiler?

like image 374
nikosd Avatar asked Dec 01 '22 16:12

nikosd


2 Answers

In Julia 0.5 or later, you can do getindex.(arr, 1) to extract the first element of each array in arr. This is quite efficient, especially because it can fuse with other elementwise operations using the "dot call" syntax.

like image 143
SGJ Avatar answered Dec 09 '22 23:12

SGJ


This cannot be done with [] indexing. Each [] operation is an independent operation (calling getindex). You have tried "slicing" the nested arrays by calling arr[:][1]. There are two independent operations here: first, (arr[:]), and then (arr[:])[1]. But in this case arr[:] == arr! Similarly for arr[1][:] — you're simply getting all the elements of the first vector. That's why the two are returning the same thing.

Your comprehension is a good solution. Unlike old* versions of MATLAB, Julia's JIT makes for loops faster than the vectorized alternatives. It takes some getting used to if you're coming from Matlab or Python. But it allows you to traverse these kinds of complicated structures in a very efficient manner.

With regards to your comment, the reason they used a vector of vectors in this case instead of a adding columns to a multidimensional array is that currently only vectors can grow. You can copy your Vector of Vectors into a two dimensional array by calling hcat(arr...), but if your vectors are very large (millions of elements) the copy itself will be fairly slow.

*(Recent versions of Matlab have a JIT, as well, which can make some for loops faster than vectorization, too, but when it kicks in is unpredictable. For loops these days are almost always faster than arrayfun/cellfun with custom functions, in my experience).

like image 44
mbauman Avatar answered Dec 09 '22 21:12

mbauman