5
votes

In Julia, is there a way to retrieve a vector containing multiple elements from a multi-dimensional array similar to numpy's advanced indexing? For instance from this 2D array:

genconv = reshape([6,9,7,1,4,2,3,2,0,9,10,8,7,8,5], 5, 3)
genconv[[1,2,3],[2,3,1]]

This results in a 3x3 array, not in a vector: screen shot

3
don't like it? [genconv[[1,2,3],[2,3,1]]...]Reza Afzalan
No, cause I'm expecting a vector with three elements.Hannes Becher

3 Answers

5
votes

To get elements by col and row index one way is to use sub2ind function:

getindex(genconv,sub2ind(size(genconv),[1,2,3],[2,3,1]))

EDIT

as already @user3580870 has commented

getindex(genconv,sub2ind(size(genconv),[1,2,3],[2,3,1])) equals genconv[sub2ind(size(genconv),[1,2,3],[2,3,1])]

what I got shows no difference in efficiency between getindex and array comprehensions syntax.

4
votes

Julia 0.5 now supports indexing by arrays of CartesianIndexes. A CartesianIndex is a special index type that spans multiple dimensions:

julia> genconv = reshape([6,9,7,1,4,2,3,2,0,9,10,8,7,8,5], 5, 3)
5×3 Array{Int64,2}:
 6  2  10
 9  3   8
 7  2   7
 1  0   8
 4  9   5

julia> genconv[CartesianIndex(2,3)] # == genconv[2,3]
8

What's interesting is that you can use vectors of CartesianIndexes to specify this numpy-style pointwise indexing:

julia> genconv[[CartesianIndex(1,2),CartesianIndex(2,3),CartesianIndex(3,1)]]
3-element Array{Int64,1}:
 2
 8
 7

That's pretty verbose and terrible-looking, but this can be combined with the new f.() special broadcasting syntax for a very nice solution:

julia> genconv[CartesianIndex.([1,2,3],[2,3,1])]
3-element Array{Int64,1}:
 2
 8
 7
3
votes

Another option is to just treat the data as a vector, rather than a multidimensional array:

genconv = [6,9,7,1,4,2,3,2,0,9,10,8,7,8,5]

genconv[ [10, 13] ]