Non scalar indexing in Julia

How do I achieve non scalar indexing in Julia?

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

julia> l[[1,2,3],[1,2,1]]
3×3 Array{Int64,2}:
 1  2  1
 2  3  2
 4  5  4

I want to assign be able to assign values to different column value in each row. In the above example, I want to select 1st element from row 1, 2nd element from row 2 and 1st element from row 3 and assign different values to each of these element. In python, I could do this using l[1,2,3],[1,2,1]]=[7,8,9] where l is a nd numpy array.
Is there an efficient way of doing this other than using loops?

Why not a loop? It seems like a perfectly reasonable approach to the problem and should be very efficient.

2 Likes

Isn’t there any way we can parallelize this? Since each assignment is applied to a different slice of array.

It’s possible, but without knowing what exactly you’re trying to do there’s no way to be sure. Can you provide an example of what you want?

1 Like
function non_scalar_indexing(arr::Array{Float32,2}, idx1::Array{Int64,1}, idx2::Array{Int64,1},value::Array{Float32,1})
    index=0
    for idx in zip(idx1,idx2)
        arr[idx[0],idx[1]]=value[index];
       index+=1;
    end
    return arr   
end

I also would like to be able to handle case where arr is Array{Float32,3} and value is Array{Float32,2}.

Loops in Julia aren’t bad! In fact, they’ll often be faster than trying to jam everything onto one line. Note that writing everything on a single line does not “parallelize” it.

I’ve often referred to the kind of indexing you’re after here as “pointwise”, and one way of compactly representing it is with CartesianIndex:

julia> l = [1  2; 2  3; 4  5]
3×2 Array{Int64,2}:
 1  2
 2  3
 4  5

julia> l[CartesianIndex.([1,2,3],[1,2,1])]
3-element Array{Int64,1}:
 1
 3
 4
2 Likes

I see. Thank you so much for the info! I assumed that the framework would exploit the non sequential behavior in pointwise operations.